React functional component communication - reactjs

I'm working on a react webapp that requires a parent component call a function in the child component when a state changes. Something like this:
function Parent() {
const [var,setVar] = useState();
useEffect(() => {
//something to call doSomething()
},[var])
return <div> <Child /> </div>
}
function Child() {
const [data,setData] - useState([]);
doSomething() {
fetch('/path/').then((resp) => {
setData(resp.data)
}
}
return <div> Child </div>
}
This is actually my first time using react so sorry if this is a stupid question. I looked into it and it doesn't seem like contexts are the best to use for this case so I was wondering if there was an easier way to call "doSomething()". Thank you.
I am using the child in 2 places in my application. That is why I want to do this.

Easiest way for you to execute doSomething in a child is, if you pass in the dependent value that affects the function execution i.e. your parent component executes the function when var changes.
Pass in the var as prop to your child component and move the effect from parent to child component.
This would mean if something in parent component changes (in this case var changes), a function in child component gets executed.

You also can do this through the use of callbacks. Pass in a callback to the child component, then pass doSomething into said callback. You then have access to the function.
function Parent() {
const [var,setVar] = useState();
// State to contain the child's function
const [doSomething, setDoSomething] = useState()
// Callback to receive the child's function
const handleDoSomething = doSomething => setDoSomething(doSomething)
useEffect(() => {
doSomething()
},[var, doSomething])
// Pass the callback to Child
return <div> <Child getDoSomething={ handleDoSomething } /> </div>
}
function Child({ getDoSomething }) {
doSomething() {return "something"}
// Pass doSomething into the callback
getDoSomething(doSomething)
return <div> Child </div>
}

Related

How to call a function immediately

I write my request in my parent Component with code below:
useEffect(() => {
// my request
}, [])
As we all know, useEffect of parent component will implement after child component, so this request will be implemented after all child components rendered.
How can I call my request immediately before my child component's useEffect?
The order of execution of useEffect in a simple parent child component like this
<Parent>
<Child />
</Parent>
is, child useEffect first and then parent's.
If you want child to wait for parent's useEffect, you can use a conditional to show something else till then:
const [showChild, setShowChild] = useState(false);
useEffect(() => {
/* other activies */
setShowChild(true);
});
return (
<>
<otherСomponents />
{showChild && <Child />
<otherСomponents / >
</>
);
Don't put you function into useEffect, just in the component body:
export default function YourComponent() {
// Your logic here
return (
...
);
}
Because your component is just a function too, your function will be called immediately.
Simply, put statement of parent useEffect to top of child component's useEffect.

How to have a React child component call a function from a parent component

I have a parent component and a child component (as a separate component file). How would I go about calling a function in the parent component from the child component?
The child component is imported into the parent component and the parent component has a function that makes an API call. I would like the child component to be able to also reach into the parent and run the api call function.
I could post the code I have but it's simply making an API call in the parent and having the child component imported in the parent.
thanks for any help.
Provide the function as a property on the child element:
const Parent = () => {
const someFunction = () => { /*...*/ };
return <Child someProp={someFunction}/>;
}
const Child = ({ someProp }) => {
return (
<div onClick={() => someProp()}>
Hello World
</div>
);
}

Is this a correct way to pass props from child to parent?

Many times, when I want to apply proper encapsulation, i.e storing form input fields data at a form component and later sending the data via an ajax call in my main component where I store the main state of the application instead of storing everything on a single component, I encounter this dilemma: Either write it all in a single component (form and ajax call), or split the work to different encapsulated components while transferring the state / props via a function callback. hence my question - is this a "correct" way to move the props up to the parent component? (In this example, just to keep it simple - logging the data from the child component via the parent component)
If not, what would be a better way?
Thanks in advance!
function Parent() {
function getChildData(data) {
console.log(data);
}
return <Child childData={getChildData} />;
}
function Child(props) {
return <button onClick={sendChildData}>Update Parent's State!</button>;
function sendChildData() {
let data = "Data from child component!";
props.childData(data);
}
}
Parent.jsx
const [childData, setChildData] = useState(null);
const Parent = () => {
const handleData = (data) => {
console.log(data);
setChildData(data);
}
return <Child onHandleData={handleData} />;
}
Child.jsx
const Child = (props) => {
const { onHandleData } = props;
return <button onClick={onHandleData("Data from child component!")}>Update Parent's State!</button>;
}

React Hooks: Setting parent state before setting child state

I've observed an interesting nuance of useState that I'm wanting to understand more deeply. The scenario:
Parent component owns some some local state created via useState
Parent passes an event handler function as a prop to a child component. This handler sets state in the parent.
Child component also has local state created by useState
When a certain event happens in the child, both the callback prop and the local state setter are called
My observation is that if the callback is run first, the a re-render of the parent is triggered which clobbers setting the child state. If I reverse the order things "seem" to be fine.
Contrived example:
Parent Component
const Parent = () => {
const [, setParentData] = useState();
function onData(data: string) {
setParentData(data);
}
return (
<Child
onData={onData}
/>
)
};
Child Component
const Child = ({
onData
}) => {
const [childData, setChildData] = useState();
function onClick() {
const data = Date.now;
onData(data);
// this call gets clobbered if onData is called first
// but is fine if I swap them
setChildData(data);
}
return (
<div onClick={onClick}>{ childData }</div>
);
};
Anyone know if ensuring child state setters are called before the parent callback is sufficient to keep all state updates, or are there other async types of things here where I may still have a race condition of some sort?

Is it possible to change the state of a container with an external function or in a child without passing in a function?

The standard onChange behavior, in React, I would like to have this behavior in the input/TextField component, instead of repeating the code every time I use the component, and able to update the parent container's state.
Otherwise it would be nice to be able to just import the behavior to use it, instead of having to rewrite it every time I am creating a new container with input/TextField component.
onChange(e) {
this.setState({[e.target.name]: e.target.value});
}
Any thoughts/solutions? (Even for why this may be a bad idea.)
It's a great idea and done a lot, try passing a callback function to Child component.
In this example, a Parent passes setValue to its child component.
Child component updates its parent state using the callback function setValue as aspected.
function Child({ onChange }) {
return <input onChange={e => onChange(e.target.value)} />;
}
function Parent() {
const [value, setValue] = useState("I'm a Parent");
return (
<>
<h1>{value}</h1>
<Child onChange={setValue} />
<>
);
}
Demo:

Resources