RecoilJS with RNN - react-native-navigation

Facebook's new RecoilJS is gaining traction as an amazing state management tool with great potential, but how can we use it with RNN if we need to wrap the root view with RecoilRoot. Is there a way to wrap the root view of a RNN app?
import {RecoilRoot} from 'recoil';
function AppRoot() {
return (
<RecoilRoot>
<SomeRootView />
</RecoilRoot>
);
}

I am currently using it like this and it seems to be working fine.
import {RecoilRoot} from 'recoil';
function AppRoot() {
return (
<SafeAreaProvider>
<RecoilRoot>
<NavigationContainer>
<BottomNav />
</NavigationContainer>
</RecoilRoot>
</SafeAreaProvider>
);
}

Related

React Typescript take part of props

I'm relatively new to React & TypeScript. I'm trying to extend an existing component by making a wrapper around it, but I am having issues trying to add my own values to the properties.
I want it so that the default properties (in a predefined type "TextFieldProps" from the MUI library) carry over, and I can add my own values to it. I'm doing this by making my own type as such:
type PinnableTextFieldProps = TextFieldProps & {
pinned: boolean;
onPin: (newValue: boolean) => void;
};
I then use it as follows:
export function PinnableTextField(props: PinnableTextFieldProps) {
return (
<TextField
{...props}
InputProps={{}}
/>
);
}
This works fine, except that the "pinned" and "onPin" values are copied over to the TextField while they shouldn't be (TextField doesn't know what they are, and an error is printed to the console because of it)
I tried to cast it using ...(props as TextFieldProps) but it still included the properties in the spread.
How would I properly split up the props spread to only include all values inside of the TextFieldProps type, so excluding the 2 values I added?
I hope someone can point me in the right direction!
Many thanks!
You could do something like this:
export function PinnableTextField(props: PinnableTextFieldProps) {
const { pinned, onPin, ...rest } = props; // <= Splitting props into pinned, onPin and all other properties into rest
// Use pinned, onPin here
// Pass the rest of the props down to the TextField
return (
<TextField
{...rest}
InputProps={{}}
/>
);
}

How to add data to SharePoint list with SPFx using React Functional component?

I have created an SPFx React solution with the Class components and performed CRUD operations with the SharePoint list.
I have used #pnp/sp for SharePoint API calls.
Now, I need to perform CRUD operations in the SPFx React solution with the Functional components.
Can anyone suggest useful links for the same?
Thanks
Its the same in Functional components.
import * as React from 'react';
import "#pnp/sp/webs";
import "#pnp/sp/lists";
import "#pnp/sp/items";
import { SPFI } from '#pnp/sp';
const SimpleFunctionComponent:React.FunctionComponent<{sp: SPFI}> = ({sp}) => {
const [ items, setItems ] = React.useState<string[]>([]);
React.useEffect(() => {
const init = async () => {
const items: any[] = await sp.web.lists.getByTitle("Test").items();
setItems(items.map(i => i["Title"]));
};
if(sp) {
init();
}
}, [sp]);
return <div>
{
items.map(i => <div>{i}</div>)
}
</div>
}
export { SimpleFunctionComponent }
You have the SPFI property (you can define and init it in the webpart.ts file). Then in the component itself you can have an useEffect hook to load items for example. The hook I use in the example will load everytime the "sp" property is changing. The result will look like this:

Rendering one of multiple pages with lit-element

The lit-element documentation describes conditional rendering via (condition ? a : b). I was wondering how to use that to render one of multiple pages, f.e. in combination with mwc-tab-bar from Googles material web components.
My current solution is something like this:
render() {
... other stuff ...
${this.selectedPage === 0 ? html`
<div>
...
</div>
` : html``}
${this.selectedPage === 1 ? html`
<div>
...
</div>
` : html``}
... further pages ...
}
I don't like the :html`` part but is that how it's meant to be?
Use more simple code like this.
constructor(){
super();
// don't forget add `prop` and `selectedPage` to `static get properties()`
this.prop = 1;
}
render() {
return this.getPage(this.selectedPage);
}
getPage(num){
switch(num){
default:
case 1:
return html`<div>P${this.prop}<div>`;
case 2:
return html`<div>P2<div>`;
}
}
There are multiple ways of achieving this, your solution is one, but as you mention, it's not the prettiest
One way you could modularize this somewhat is using an object/array and render functions, basically the idea is this:
First, define render functions for each page (this can be on the same file or on different files):
const page0Renderer = (context) => {
return html`<section>${context.someData}</section>`;
};
Then, you could define an object that has a match between the page identifiers and their respective functions, you are using numbers so the sample below uses numbers:
const pageRenderers = {
'0': page0Renderer,
'1': page1Renderer,
'2': page2Renderer,
// etc
};
And in your main render function you could use all these like this:
render() {
return html`
${pageRenderers[`${this.selectedPage}`](this)}
`;
}
This would basically call the render function that matches the selected page and send it a reference to the main web component so that you can access its properties.
Then again, this approach also has its flaws and I wouldn't really recommend it much if you need your child templates to be complex.
In that case, instead of rendering functions you probably would be better off creating other components for each view and that way you could also do some lazy loading and so on.
For that kind of approach, you might want to check out routers like vaadin router which help you both with routing and changing which component gets displayed accordingly

Testcafe: using Test Controler in boundTestRun not working

I'm trying to work with shadow roots in my Testcafe project. It's a little bit complicated to deal with it. I create a custom function that behaves the same as Selector().find() but I struggle with this error :
The "boundTestRun" option value is expected to be a test controller.
when I'm doing as documented here :
import { Selector, t } from 'testcafe'
getInShadowRoot = Selector(
// More code here
)
const boundedGetInShadowRoot = this.getInShadowRoot.with({ boundTestRun: t })
I create a gist to illustrate my problem: https://gist.github.com/HugoDel/a600f3e120674e3f255884f3dc84fee3
Thanks for your help!
Edit:
I finally get rid of it since I don't need to add .with({ boundTestRun: t }) to make it work.

How to organize your static text in a single page app?

Imagine you have a single page applications with lot of static text in a reactjs app.
for example :
import Block from './components/block';
const arr = [
{
name: 'block1',
text: '<p>Lot of static text 1</p>'
},
{
name: 'block2',
text: '<p>Lot of static text 2</p>'
},
{
name: 'block3',
text: '<p>Lot of static text 3</p>'
},
{
name: 'block4',
text: '<p>Lot of static text 4</p>'
}
];
...
render() {
return (
arr.map((a, i) => {
return (
<Block key={i} text={a.text} />
);
})
);
}
...
So the "Lot of static text" are very bigger.
How do you organize this text in all components ? Do you create a model.js file in the repo components or something ? there are a best practice for this ?
Thanks :)
You can create one JSON file for the same and fetch each detail using http.
You can store you data in some Global Service and use whenever needed by importing that file.
Also you can create model.js file for the same.
But i would like to suggest first one, if you have to use for limited time else second option is good.
ES7 suggests to store static data and methods inside static classes (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/static). This is the current best practice.

Resources