Pass Data from Parent To Child Component in ReactJs - javascript

In App.Js file I'm passing "This data is coming from Parent" to Child.Js
But here I want to pass this on button through onClick not dataParentToChild={data}. Just Like Child.Js file working in onClick={handleChildToProp}
enter the link description here
App.Js
function App(props) {
// Child To Parent
const [word, setWord] = useState("");
const handleChildToParent = (words) => setWord(words);
// Parent To Child
const data = "This data is coming from Parent";
return (
<>
<h1>"Parent Data"</h1>
<h2>{word}</h2>
<Child
// Without button Working Fine
dataParentToChild={data}
// With button Working Fine
dataChildToParent={handleChildToParent}
/>
</>
);
}
Child.Js
const Child = (props) => {
// Parent To Child
const handleChildToProp = () => {
props.dataChildToParent("This data is comming from Child");
};
return (
<>
<h1>Child Components</h1>
<h2>{props.dataParentToChild}</h2>
<button onClick={handleChildToProp}>Data Child To Parent</button>
</>
);
};

You need to make the button onClick update a state to trigger a re-render of dataParenToChild, like so:
function App(props) {
// Child To Parent
const [word, setWord] = useState('');
const [parentToChild, setParentToChild] = useState('');
const handleChildToParent = (words) => setWord(words);
// Parent To Child
const handleParentToChild = () => {
setParentToChild('This data is coming from Parent');
};
return (
<>
<h1>"Parent Data"</h1>
<h2>{word}</h2>
<button onClick={handleParentToChild}>Data Parent To Child</button>
<Child
// Without button Working Fine
dataParentToChild={parentToChild}
// With button Working Fine
dataChildToParent={handleChildToParent}
/>
</>
);
}
Working solution

Related

ReactJS while passing function from parent to child and accessing parent state not returning completely

I was trying to access Parent state when a function is called from Child component, for that created a function in Parent component and passed it to Child, issue is I am not able to access the state completely.
for example on button click I add a new input field and a delete button, suppose I added 10 input fields, and added all of them in state array, but when i click delete button of second input field, the count I get from state is 1, similar if I click 5th delete button i get count as 4 and it only show me 4 items in state, but it has 10 items
Here is an example link https://codesandbox.io/s/add-react-component-onclick-forked-t2i0ll?file=/src/index.js:0-869
import React, { useState } from "react";
import ReactDOM from "react-dom";
const Input = ({ deleteRow, position }) => {
const handleDelete = () => deleteRow(position);
return (
<>
<input placeholder="Your input here" />
<button onClick={handleDelete}>Delete</button>
</>
);
};
const Form = () => {
const [inputList, setInputList] = useState([]);
const onDeleteRow = (position) => {
console.log("inputCount", inputList);
};
const onAddBtnClick = (event) => {
setInputList(
inputList.concat(
<Input
key={inputList.length}
position={inputList.length}
deleteRow={onDeleteRow}
/>
)
);
};
return (
<div>
<button onClick={onAddBtnClick}>Add input</button>
{inputList}
</div>
);
};
ReactDOM.render(<Form />, document.getElementById("form"));
It's called a stale closure.
You can avoid that by not storing react elements inside the state.
Example:
const Form = () => {
const [inputList, setInputList] = useState([]);
const onDeleteRow = (position) => {
console.log("inputCount", inputList);
};
const onAddBtnClick = (event) => {
setInputList([...inputList, inputList.length])
);
};
return (
<div>
<button onClick={onAddBtnClick}>Add input</button>
{inputList.map(item => (
<Input
key={item}
position={item}
deleteRow={onDeleteRow}
/>
)}
</div>
);
};

Passing data from a child component to a parent component (React)

I have a child component that has some states which change in value when you check or un-check some boxes; I want to be able to pass those state values to the parent component. I've tried a few things on the internet but nothing seem to work.
I've tried to (Parent Component File):
const ParentComponent = () => {
const [ data, setData ] = useState();
const childToParent = (childData) => {
setData(childData);
};
return(
<Child childToParent={childToParent} />
);
}
and on the Child Component:
const ChildComponent = ({ childToParent }) => {
const [ childData, setChildData ] = useState(false);
const handleChange = () => {
setChildData(!childData);
childToParent(childData);
};
return(
<div>
<Checkbox value={childData} callback{() => handleChange()} />
</div>
);
}
Basically the problem is I dont get how to move data from a child component to a parent component.

React - Rxjs: Transform a parent component event handler in a stream

Given a parent component renders the following:
const handleButtonClick = (e) => {
//code omitted
}
<ChildComponent
handleButtonClick={handleButtonClick}
/>
And the child component which adds this handler to a button:
const ChildComponent = (props) => {
const handleButtonClick = props.handleButtonClick
return (
<button onClick={handleButtonClick}>Click me!</button>
)
}
How would I transform handleButtonClick in the parent in a Rxjs Stream?
I have thought of one way, which is creating a subject:
const clickStream = new Subject()
const handleButtonClick = (e) => {
clickStream.next(e)
}
I would also be interested in how to do that in a scenario where the parent renders multiple, dynamic children, e.g.:
return(
<>
{
children.map((child, index) => {
<ChildComponent handleButtonClick={handleButtonClick}/>
})
}
</>
)

Pass functional component from child to parent in React

Is it possible to pass a functional component from a child component to a parent component? I'm trying to do a dynamic modal that is displayed inside the parent but that the children can populate through a function from a provider, for example:
setModal(() => (
<div>content</div>)
)
And the parent receives this component:
const [modal, setModal] = useState(false)
const [modalContent, setModalContent] = useState<FunctionComponent>()
...
<Provider value={{
setModal: (content: FunctionComponent) => {
setModalContent(content); // This updates the state to hold a function component and to re-render
setModal(true); // This updates a state flag to show the overlay in which the modal is rendered
},
}}>
...
</Provider>
The content of the modal should be dynamic. I was trying to use the state of the component to hold the functional component but I don't think if that's possible or if it's a good practice.
If I understand your question correctly, you're still looking to pass a function from the parent to each child but each child should be able to change the state of a modal component that the parent also has ownership over.
For the above scenario this is something you can do:
const Provider = ({ children, updateModal }) => {
// With this, every child has the ability to call updateModal
return React.Children(children).map(child => cloneElement(child, { updateModal }));
};
const ModalComponent = ({ open, children }) => {
if (!open) return null;
return (
<dialog>
{children}
</dialog>
);
};
const ParentComponent = () => {
const [modal, setModal] = useState(false);
const [modalContent, setModalContent] = useState(null);
const updateModal = (content) => {
setModalContent(content);
setModal(true);
};
return (
<>
<Provider updateModal={updateModal}>
{...insert children here}
</Provider>
<ModalComponent open={modal}>
{modalContent}
</ModalComponent>
</>
);
};

React conditionally render component using an outside function

I'm working on a modal function in an application. Since the app has different modals, I have a function which handles the open & close state of various windows:
OpenItem.jsx
const OpenItem = ({ toggle, content }) => {
const [isShown, setIsShown] = useState(false);
const hide = () => setIsShown(false);
const show = () => setIsShown(true);
return (
<>
{toggle(show)}
{isShown && content(hide)}
</>
);
};
export default OpenItem;
Header.jsx
Now in my main component, I want to to use this function with another component:
const Header = () => {
return (
<div>
<OpenItem
toggle={(show) => <Button onClick={show}>icon</Button>}
content={(hide) => (
// Component to hide:
<ComponentToShowOrHide onClick={hide} />
)}
/>
</div>
);
};
export default Header;
This works fine, except that instead of having the {hide} function as a part of the imported component, I want to toggle the view in <Button onClick={show}>icon</Button>
My idea is to conditionally render the show or hide in the button instead of rendering it in the component, but I'm not quite sure how to do that since I haven't used an outside function to control a function in a component.
Simply write a function that toggles the state rather than sets it to a value.
const OpenItem = ({ toggle, content }) => {
const [isShown, setIsShown] = useState(false);
return (
<>
{toggle(() => setIsShown(prevState => !prevState))}
</>
);
};
export default OpenItem;

Categories