how do I pass ref to state? - react-native

I created a ref and passed it to the component as an argument. Now how can I write it to State without dispatch?
const myRef = createRef<any>();
const KeyboardAvoidingWrapper: React.FC<IKeyboardAvoidingProps> = (
props: IKeyboardAvoidingProps,
=> {
if (isAndroid) {
return (
<ScrollView ref={myRef} style={styles.scroll} contentContainerStyle={styles.scrollContent}>
<KeyboardAvoiding>{props.children}</KeyboardAvoiding>
</ScrollView>
);
}

This example might help you.
<Component ref={(ref) => {
// You can now write ref to state,
// which I will not recommend
// or pass it to callback
props.getInnerRef(ref);
}} />
// You need to pass getInnerRef
<Component getInnerRef={(ref) => {
this.innerRef = ref;
}}

const FancyButton = React.forwardRef((props, ref) => (
<button ref={ref} className="FancyButton">
{props.children}
</button>
));
// You can now get a ref directly to the DOM button:
const ref = React.createRef();
<FancyButton ref={ref}>Click me!</FancyButton>;
Please refer the react documentation. It clearly defines how to use refs.
ForwadingRefs

Related

React hook form with customize controller

<Controller
name={'productType'}
control={props.control}
render={({ field: { value, onChange, onBlur } }) => {
return (
<SelectInput
options={productTypeOption}
label={'Product Type'}
isDisabled={isDisabled.productTypeDisable}
onChange={onProductTypeChange}
isLoading={isLoading.productType}
statusMsg={productTypeOption.length}
/>
)}}>
</Controller>
I got my select input componenet from react-select package and i want to use react hook form controller with it btw i already got my own onChange props on it , In docs to send data to useForm i also need to put field onchange on it so how to bring onChange useForm with my own logic???
const onProductTypeChange = (e) => {
setServiceOtherOption([])
setServiceQuantitesOption([])
const valueSelect = e.value
props.setJobData((arr) => ({
...arr,
productType: valueSelect
}
))
}
this is my on change needed
You can set onChange prop on SelectInput as a function which calls your onProductTypeChange function and also call onChange of react-hook-form, like this:
<SelectInput
onChange={(e)=> {
onProductTypeChange(e);
onChange(e.value);
}}
...
/>

React native MobX store - MobX injector: Store is not available

I'm using the following template: https://github.com/cawfree/create-react-native-dapp
I have used the provider component in the top level (parent) component like so:
import { Provider } from 'mobx-react';
import SettingsStore from '../../store/settings';
return (
<Provider store={SettingsStore}>
<View style={[StyleSheet.absoluteFill, styles.center, styles.white, !loading && {justifyContent: 'space-between'}]}>
{loading ?
<FadeOutImage />
:
<Welcome />
}
</View>
</Provider>
);
Here's my SettingsStore in file settings.js:
import {makeAutoObservable} from 'mobx';
class SettingsStore {
darkMode = false
constructor() {
makeAutoObservable(this)
}
toggleDarkMode = () => {
this.darkMode = !this.darkMode
}
}
export default new SettingsStore();
The following is where I am injecting the store. It's the child component <Welcome />:
import { inject, observer } from "mobx-react";
const Welcome () => {
return (<View><Text>test</Text></View>)
}
export default inject("SettingsStore")(observer(Welcome));
I have checked that the paths for the imports is correct (would get another error otherwise). I just cannot understand why I am seeing the following err:
What's going wrong and how can I fix this?
You passing in under the name store into Provider (<Provider store={SettingsStore}>), so when injecting you need to use same prop name inject("store"). Or change prop name to SettingsStore: <Provider SettingsStore={SettingsStore}>

Creating new record does not register in list without refresh and creates duplicate record

Below is a screenshot of the Redux dev tools. This is a list of records of a particular resource. As you can see, the newly added record has a duplicate with the key undefined. It also does not register on the list without a refresh.
Redux Dev Tools
Here is the create component:
export const OrgCreate = (props: ReactAdminComponentProps) => {
const controller = useCreateController(props);
return (
<Create {...props} {...controller}>
<SimpleForm>
<TextInput source="name" />
</SimpleForm>
</Create>
);
};
Here is the list component:
export const OrgList = (props: ReactAdminComponentProps) => {
const controller = useListController(props);
return (
<List {...props} {...controller} exporter={false} bulkActionButtons={false}>
<Datagrid rowClick="edit" hasBulkActions={false}>
<TextField source="name.value" label="Name" />
<DateField source="createdAt" />
</Datagrid>
</List>
);
};
Here is the create response in the GraphQL provider:
createResponse = (data: any) => data.createOrganization.organization;
Try removing the lines:
const controller = useCreateController(props);
const controller = useListController(props);
and further {...controller}, it should work.

React Router V4 restore navigation state from url

Let's say we display a dropdown and on select the user is navigated to a different subpage via react router. How can we restore the dropdown selection on page reload with react router? The projectNumber param is only accessible in the Project component.
In some other projects I solved this problem by writing back the route param to a context or redux store from the child component, but this obviously isn't a nice solution, is it?
export const Projects: React.FC = () => {
const { data, loading, error } = useSomeData()
const history = useHistory()
const onSelectProject = useCallback(
(projectNumber: unknown) => {
history.push(`/project/${projectNumber}`)
},
[history],
)
if (error) return <p>{error.toString()}</p>
return (
<>
<Select loading={loading} onChange={onSelectProject} placeholder="Select a project">
{data?.map((project) => (
<Option key={project.id} value={project.number}>
{project.name}
</Option>
))}
</Select>
<Route path="/project/:projectNumber" render={() => <Project />} />
</>
)
}
You can do it via react-router state. Just see the example:
export const Projects = () => {
const history = useHistory()
const { state } = useLocation()
const onSelectProject = useCallback(
(projectNumber) => {
history.push({
pathname: '/project',
state: {
projectNumber
}
})
},
[history],
)
if (error) return <p>{error.toString()}</p>
return (
<>
<Select loading={loading} onChange={onSelectProject} placeholder="Select a project">
{data?.map((project) => (
<Option key={project.id} value={project.number}>
{project.name}
</Option>
))}
</Select>
{state && state. projectNumber && <Project projectNumber={state.projectNumber} />
</>
)
}
It will work fine for reload page, but not for sharing link to someone other.
But if you are going to share link with preselected dropdown, you can use query parameter (GET parameter).

How can I pass a component as a prop in React Native?

In my AutoSuggest Component (which renders FlatList), I would like to render different types of cells.
I'd like to pass different Components into AutoSuggest, such as:
<Suggest
customCell={<SimpleUserCell/>} //or any type of cell
/>
Inside Suggest.js, my render will look like this:
render(){
<FlatList
renderItem={(props) => {
return(
<this.props.customCell extraData={this.suggestData}/>
)
}}
/>
}
How can I achieve this?
To pass a component as a prop in React Native you can do the following, can be seen at: https://codesandbox.io/s/6v24n3q92z Hopefully this helps. You will need to extrapolate to get your specific use case working.
class ComponentOne extends React.Component {
render() {
return (
<div>
I am Component One see my array
<ul>{this.props.extraData.map(number => <li>number {number}</li>)}</ul>
</div>
);
}
}
class Suggest extends React.Component {
render() {
var anArray = [1, 2, 3, 4, 5];
var CustomComponent = this.props.customCell;
return <CustomComponent extraData={anArray} />;
}
}
function App() {
return <Suggest customCell={ComponentOne} />;
}