pass an array from a child to parent ReactJS - javascript

i have an array in a component i want to export it or pass it to other component (parent)
child component :
export default function child(){
const arr = ["1020","52214","3325"]
return (
<div> child</div>
)
}
parent :
export default function parent(){
return (
<>
<div> parent</div>
<child/>
</>
)
}

In react we don't pass values from child to parent but the other way around: it's a one-way data flow!
You can useState to create a stateful value and a set-function in the parent, pass the set function to the child and allow it to set the value.
Example:
export default function child(props){
const arr = ["1020","52214","3325"];
props.setMyArray(arr);
return (
<div> child</div>
)
}
import { useState } from 'react';
export default function parent(){
const [myArray, setArray] = useState([]);
return (
<>
<div> parent</div>
<child setMyArray={setArray}/>
</>
)
}
}

You can't pass data from child to parent.
You can pass like this.
const ParentPage = () => {
const [arr , setArr ] = useState([])
console.log(arr) // [1,2,3]
return (
<ChildPage setArr={setArr} />
);
}
const ChildPage = ({setArr}) => {
return (
<button onClick={()=> setArr([1,2,3]) }}> </button>
);
}
or you can do with redux

You can use props to call a function in the parent element and pass an argument in the function from the child element.
Here's an example:
Child element:
export default function child(props){
const [arr,setarr]= useState(["1020","52214","3325"]);
return (
<div onclick={()=>{props.func(arr)}}> child</div>
)
}
Parent element:
export default function parent(){
function passvalue(arr){
const passedvalue = arr;
}
return (
<>
<div> parent</div>
<child func={passvalue}/>
</>
)
}

Related

How can I update the state of a child component from the parent component in ReactJS?

I've tried passing a function as a prop to the child component, but I'm not sure how to call it from the parent component.
// Parent Component
function Parent() {
const [childState, setChildState] = useState(false);
const handleClick = () => {
// How can I update the state of the child component from here?
};
return ( <div> <Child childState={childState} setChildState={setChildState} /> <button onClick={handleClick}>Update Child State</button> </div> );
}
// Child Component
function Child({ childState, setChildState }) {
return ( <div> <p>Child State: {childState.toString()}</p> </div> );
}
in your example you do not need to pass "childState, setChildState" in to the child function as it already has access to them.
Something like this should work for you
function Parent() {
const [childState, setChildState] = useState(false);
// We have access to childState here
function Child() {
return ( <div> <p>Child State: {childState.toString()}</p> </div>
); }
// Updating state
const handleClick = () => {
setChildState(!childState)
};
return ( <div>
<Child childState={childState} setChildState={setChildState} />
<button onClick={handleClick}>Update Child State</button> </div>
);
}

React JS pass the data or child component to parent component

Is it possible to pass the data from the child component to the parent component using props?
-Parent component
--- ItemList component.
--- DisplatSelect component from the itemList component
I have a list of item in the child component which came from to the parent component, then I want to send the index of the selected data to the other child component located in the parent component.
Can't example well, kindly see the attached screenshot for other references.
Thanks a lot!
enter image description here
You can keep the data in the Parent component and use a function to pass the props from the child to the Parent. This concept is called Lifting State Up where you define the state at the highest common ancestor so all the child components are using the same data which in this case is the selecetd item
function Parent() {
const [selectedItem, setSelectedItem] = useState(null);
const data = []; // Your Data
return (
<>
<h1>Your selected Item = {selectedItem}</h1>
{data.map((item) => {
<Child item={item} setSelectedItem={setSelectedItem} />;
})}
</>
);
}
function Child({ item, setSelectedItem }) {
return <Button onClick={() => setSelectedItem(item.id)}> {item} </Button>;
}
The simplest way, I think, is for the child component where the selection is made to accept a function properly, something like onSelectionChanged. If you had a button for each item passed to the child you could do something like:
Child Component A
const ChildA = ({ items, onSelectionChanged }) => {
return (
<div>
{items.map((item, index) => (
<button onClick={() => onSelectionChanged(index)}>Item</button>
))}
</div>
)
}
Child Component B
const ChildB = ({ selectedItem }) => {
return (
<div>
Selected {selectedItem}
</div>
)
}
Parent Component
const Parent = () => {
const [selection, sets election] = useState({});
const onSelectionChanged = index => {
console.log(`ChildA selection changed: ${index}`);
}
return (
<div>
<ChildA items={items} onSelectionChanged={onSelectionChanged} />
<ChildB selectedItem={selection} />
</div>
)
}
So when your child component handles a change in the selection, it invokes the function passed as a prop onSelectionChanged. You can pass whatever data you want from ChildA to that function.
Note that the parent Component keeps the selected value (from ChildA) in local state, then passes that value to ChildB via a prop.
You can have a state variable in the parent component and pass it to child components to share data between them. I'll post a sample code block on how you can do this for your case.
export default function ParentComponent (props) {
const data = ['image_1_url', 'image_2_url', ...] // Data for the images
const [selectedIndex, setSelectedIndex] = useState(-1); // Selected index (-1 represents no selection)
return (
<ImageList data={data} selectImage={setSelectedIndex} />
{(selectedIndex !== -1) ? (<SelectedImage data={data[selectedIndex]} />) : (<No ImageSelected/>)}
);
}
And the image list component can then use the selectImage prop to select the image
export default function ImageList (props) {
return (
<div>
props.data.map((imageUrl, index) => (
<div onClick={() => {props.setSelected(index)}}>
<img src={imageUrl}/>
</div>
))
</div>
);
}
Yes it's possible. We have one parent state value and update every on click child component to the component.
import React, { useState } from "react";
const Child1 = (props) => {
return (
props.items.map( (item, index) => (
<button key={index.toString()} onClick={() => { props.updateIndex(item.id) }}>
{item.name}
</button>
) )
)
}
const Child2 = (props) => {
return (
<h1>Item selected: {props.selectItem}</h1>
)
}
const ParentComponent = () => {
const listItems = [
{
id:1,
name: "sample name 1"
},
{
id:2,
name: "sample name 2"
}
]
const [selectItem, setSelectItem] = useState('None');
return (
<>
<Child1 items={listItems} updateIndex={setSelectItem}/>
<Child2 selectItem={selectItem}/>
</>
)
}
export default function App() {
return (
<div className="App">
<ParentComponent/>
</div>
);
}

How to render multiple components with different component name?

I have a few components, they have the same parameter with iterative values, like this:
import React from "react";
import Panel from "./Panel";
import Navbar from "./Navbar";
export default function App() {
return (
<div className="App">
<Panel id={1} />
<Navbar id={2} />
</div>
);
}
const Panel = ({ id }) => {
return (
<div>The id is {id}</div>
);
};
const Navbar = ({ id }) => {
return (
<div>The id is {id}</div>
);
};
Working example here: https://codesandbox.io/s/staging-pond-mpnnp
Now I'd like to use map to render those components at once in App.js, something like this:
export default function App() {
const compnentArray = ['Panel', 'Navbar'];
const RenderComponents = () => {
let _o = [];
return (
componentArray.map((item, index) => _o.push(<{item} id={index} />))
)
}
return (
<div className="App">
{RenderComponents()}
</div>
);
}
So that item renders component names. Is this possible?
Sure, you could make use of Array.map()'s second parameter which gives you the index in the array:
import React from "react";
import Panel from "./Panel";
import Navbar from "./Navbar";
const components = [Panel, Navbar];
export default function App() {
return (
<div className="App">
{components.map((Component, i) => (
<Component key={i} id={i + 1} />
))}
</div>
);
}
As mentioned in React's documentation, to render a component dynamically, just make sure you assign it to a variable with a capital first letter and use it like you'd use any other component.
You could swap strings with your actual component references and itererate over them directly in your JSX part, like this :
export default function App() {
const componentsArray = [Panel, Navbar];
return (
<div className="App">
{componentsArray.map((Component, index) => <Component key={index} id={index + 1} />)}
</div>
);
}
Though I would suggest to memoize them to improve performance once you're confortable enough with React to start using memoization.
import React from "react";
import Panel from "./Panel";
import Navbar from "./Navbar";
const components = [Panel, Navbar]; // notice you are using the components as items, not strings;
/*
if the components need props from the parent,
the `renderComponents()` function should be declared
inside the parent component (and possibly with a `useCallback()`
hook, to avoid unnecessary re-declarations on re-renders)
*/
function renderComponents() {
return components.map((comp, index) => <comp key={index} id={index} />) || null;
}
export default function App() {
return (
<div className="App">
{renderComponents()}
</div>
);
}

How to access properties in child from children props in react

The title is pretty straightforward, I need to access a property (a ref to be precise) on a child element that is passed through the children of my component, which means that I can't pass the ref in the parent afaik.
Here's a minimal example to highlight my issue:
import React from "react";
class Child extends React.Component {
myRef = React.createRef();
render() {
return <div ref={this.myRef}>child</div>;
}
}
const Parent = ({ children }) => {
const myChild = React.Children.toArray(children).find(
child => child.type === Child
);
// I want to access this
console.log(myChild.myRef);
// but it's undefined
return (
<div>
<h1>Parent</h1>
{children}
</div>
);
};
// I can't really change this component
export default function App() {
return (
<div className="App">
<Parent>
<Child />
</Parent>
</div>
);
}
I made a codesandbox highlighting my issue https://codesandbox.io/s/eloquent-wing-e0ejh?file=/src/App.js
Rather than declaring ref in <Child/>, you should declare ref in your <Parent/> and pass it to the child.
import React from "react";
class Child extends React.Component {
render() {
return <div ref={this.props.myRef}>child</div>;
}
}
const Parent = ({ children }) => {
const myRef = React.useRef(null);
// access it from here or do other thing
console.log(myRef);
return (
<div>
<h1>Parent</h1>
{ children(myRef) }
</div>
);
};
export default function App() {
return (
<div className="App">
<Parent>
{myRef => (
<Child myRef={myRef} />
)}
</Parent>
</div>
);
}

Ref from Dropdown.Button (antd)

How can I get a ref to a Dropdown.Button (it is antd), when I set a ref to it, it returns a wrapper ?
parent = null;
parentRef = node => (this.parent = node);
render(){
return (
<Dropdown.Button
ref={this.parentRef}
overlay={menu}
type="primary"
>
content
</Dropdown.Button>
)
}
You need to use reference API, useRef or React.createRef.
Refer to Refs and the DOM in React:
class App extends React.Component {
buttonRef = React.createRef();
componentDidMount() {
console.log(this.buttonRef);
}
render() {
return (
<Dropdown.Button ref={this.buttonRef} overlay={menu} type="primary">
content
</Dropdown.Button>
);
}
}
With hooks:
const App = () => {
const buttonRef = useRef();
useEffect(() => {
console.log(buttonRef);
}, []);
return (
<FlexBox>
<Dropdown.Button ref={buttonRef} menu={menu}>
drop down
</Dropdown.Button>
</FlexBox>
);
};
Hei,
Check out the React.forwardRef() here.
It's a function which you can wrap your 'child' component and it's specifically designed to make possible parent to have a reference to its children. Should solve your problem.
Cheers!
you can by passing a cb function on the ref attrib:
parent = null;
parentRef = ref => (this.parent = ref);
render(){
return (
<Dropdown.Button
ref={parentRef}
overlay={menu}
type="primary"
>
content
</Dropdown.Button>
)
}
Or with useRef hook:
for functional components no classes
const parentRef =React.useRef(null);
return (
<Dropdown.Button
ref={parentRef}
overlay={menu}
type="primary"
>
content
</Dropdown.Button>
)

Categories

Resources