Pass SetState from parent component to a child component in React Native - javascript

In React js I would pass setState like below from parent components to child components, however in React Native setABC is undefined. What's the best way to achieve the below in React Native?
Parent.js:
function Parent(){
const [ABC, setABC] = useState();
return(
<routes>
<route path="/child" element={<Child setABC={setABC} />} />
</routes>
);
}
export default Parent;
Child.js:
function Child({setABC}){
let doSomeStuff = () =>{
setABC("ABC");
}
}
export default Child;

the problem is not related to react-native
you passed the prop as setState in parent.js
<Child setState={setABC} />
and received it as setABC function Child({setABC}){
it should be like this
function Child({setState}) {
...
}
or change the prop name in Parent.js to match Chlid.js
<route path="/child" element={<Child setABC={setABC} />} />

Related

How to call a Component which name is passed as props in React?

i'm new at React. Basically i want to call different components based on the string passed as props. I've component named Device that have as prop the name of a particular device and in Device i want to call another components which has as name the props. Something like this: <DeviceName/>
This is my code:
App.js
<Device name = {devName} />
Device.js
import DeviceMark from ./devices/DeviceMark
function DeviceName({devName}) {
const DevName = devName;
return (
<Router>
<Switch>
<Route path = "/" exact><DevName /></Route>
</Switch>
</Router>
)
}
Imagine that in this case DevName will replace DeviceMark
When you really need to convert string component names to actual components while rendering, I can suggest following way
import DeviceMark from ./devices/DeviceMark
function DeviceName({devName}) {
const mappingComponents = {
foo: FooComponent,
bar: BarComponent,
deviceMark: DeviceMark
};
const ComponentToRender = mappingComponents[devName || 'foo'];
return (
<Router>
<Switch>
<Route path = "/" exact><ComponentToRender></ComponentToRender></Route>
</Switch>
</Router>
)
}
More details in official doc - https://reactjs.org/docs/jsx-in-depth.html
I guess you need to use React.createElement. It allows to create React element from string (if it's a basic html tag) or from function (if it's a React component).
import React from 'react'
import ReactDOM from 'react-dom'
const DeviceName = () => {
return 'sub component'
}
const Device = ({subDev}) => {
return (
<div>
{ React.createElement(subDev) }
</div>
)
}
function App() {
return <Device subDev={DeviceName} />
}
ReactDOM.render(<App />, document.getElementById('root'))
It's a little example. I have a main component Device. It accepts a sub-component via a prop and I pass sub-component to createElement. It does not matter if sub-component whether basic html tag or React component.
It's codesandbox example.

defining a function to pass it as props, but I get a compiling error

I have a react component that is trying to pass a function to another component, the problem is that
I'm not being able to define the function, it throws a compiling error
export default function App() {
createActivity() { // here I get an error: missing semicolon
console.log("creating activity");
}
return (
<div className = "App" >
<Route path="/" component={ Header } />
<Route exact path="/" component={ShowSplashWindow} />
<Route path="/createactivitiy" render = {() =>
<CreateActivity createActivity={this.createActivity} />} />
</div>
);
}
What am I missing?
Rafael
The function has to be declared as
const createActivity = () => {
console.log("creando la actividad");
}
And when passed as props, it should not be called with "this"
<CreateActivity createActivity={createActivity} />}
You declared component as functional, but trying to create a class method.
You should either use class component:
export default class App extends React.Component {...
with 2 methods: createActivity and render.
Or declare your function and assign to constant
const createActivity = () => ...
but use it without this:
<CreateActivity createActivity={createActivity} />

Is there a way to export setState outside stateless components in react?

Consider this example
export function InsideHoc(props){
const [A, setA] = useState(false);
return({if(A) && (<h1>Print something</h1>)});
}
In another file
import {A, setA} from './inside-file';
function ToggleFromOutside(){
return(<p onClick={setA(!A)}>Verify</p>);
}
Can setA be exposed outside so that the state of this component be changed from outside? I know this can be done through redux. But without using this, is there a way to change the state of one component?
Structure is like this
import {withCreateHOC} from './external';
import childComponent from './child';
class A extends React.Component {
render(){
<Another menus={(item) => <MenuItems object={item} />}
/>
}
}
export default withCreateHOC(A, {custom: childComponent, title: 'Add'});
//withCreateHOC renders modal here as well as it has a button to toggle the state. Same state should be used from below function
function MenuItems(){
return(<button onClick={displayModal}>)
}
Yes.
You can lift the state in that case. This works good if you don't need to pass down the setState to far down the tree.
If you don't want to pass the setState function all the way down the React element tree, you will need to use context, redux or some other state handling.
Example state lift
export function Parent(){
const [message, setMessage] = useState("Hello World");
return (
<>
<Child1 message={message} />
<Child2 changeMessage={setMessage} />
</>
);
}
// Can be in other file
function Child1(props){
return(<p>{props.message}</p>);
}
// Can be in other file
function Child2(props){
return(
<a onClick={() => props.changeMessage("Changed")}>
I can change things in other components.
</a>
);
}
Example of React tree with shared context/redux
<WithRedux>
<App>
<Navigation />
<Modal />
<PageRenderer />
<SomeList>
<ListItem />
<ListItem />
</Somelist>
</App>
<WithRedux>
All the children of the WithRedux component can access the state and modify it.
(PS: You can wrap the App with the HOC withRedux etc, this example is just for visualization)

Pass down function from parent component to child component is not working

The function is not triggering. I checked many other answers and it seems like my code should be working.
In App parent component:
update() {
console.log("hello");
}
<PrivateRoute
exact
path="/profile"
component={Profile}
update={this.update}
/>
In Profile child component:
<button
type="button"
onClick={this.props.update}
>
I think in PrivateRoute you are not passing update method to Profile component.
const PrivateRoute = ({ component: Component, path: Path, ...rest }) => (
//...rest of your code
//pass update prop along with other props which are needed.
<Component update={rest.update} />
//...rest of your code
);
}}
/>
);
Hope this helps.

Trouble passing props to componentDidMount in child component (React)

I'm having issues passing a prop to a componentDidMount() call in a child component on my React application.
In my App.js I am passing props via Router like below:
App.js
class App extends Component {
state = {
city: ""
}
componentDidMount() {
this.setState({city: this.props.city});
}
render() {
return (
<div>
<Route path="/" exact render = {() => <Projections city={this.state.city} />} />
<Route path="/:id" component={FullPage} />
</div>
);
}
}
In my Projections.js I have the following:
Projections.js
constructor(props) {
super(props);
this.state = {
location: this.props.city
}
}
componentDidMount () {
console.log(this.state.location);
console.log(this.props.city);
}
console.log(this.state);' returns an empty string.console.log(this.props.city);` returns an empty string as well.
But I need to access the value of the city prop within componentDidMount(). console.log(this.props.city); within render() returns the prop, but not in componentDidMount()
Why is this and how do I return props within componentDidMount()?
In the constructor you should reference props, not this.props:
location: props.city
<Route path="/" exact render = {() => <Projections city={this.state.city} {...this.props} />} />
Try passing rest of props in route
this is because you assigned props in constructor that time it may or may not receive actual value. And it gets called only once in a component lifecycle.
You can use componentWillReceiveProps to get props whenever it receive and update state accordingly.
Inside Projections.js
UNSAFE_componentWillReceiveProps(nextProps){
if(nextProps.city){
this.setState({location:nextProps.city})
}
}
Here is working codesand

Categories