I have this parent App.jsx
, with two components <Child1/>
and <Child2/>
imported.
export default function App() { const [isFlipped, setIsFlipped] = React.useState(false); const handleSelectPlayers = () => { setIsFlipped(true); } const handleDeselectPlayers = () => { setIsFlipped(false); } return ( <Flippy isFlipped={isFlipped} flipDirection="horizontal" // horizontal or vertical style={{ width: "400px", height: "600px" }} /// these are optional style, it is not necessary > <FrontSide> <Child1 onSelectPlayers={handleSelectPlayers} /> // <----- </FrontSide> <BackSide> <Child2 onDeselectPlayers={handleDeselectPlayers} /> // <----- </BackSide> </Flippy> ); }
This is Child1.jsx
, where I have ‘players’ set locally by this.setState()
:
class Child1 extends Component { constructor(props) { super(props); this.state = { players:[] }; } async getPlayers() { const res = await fetch("/json/players.json"); const data = await res.json(); const players = Object.values(data.Players) this.setState({ players: players },() => console.log(this.state.players)); } handlePlayers = () => { this.props.onSelectPlayers(); }; render() { return ( ... <Button handleClick={() => this.handlePlayers()}></Button> ... );
And here Child2.jsx
, which needs ‘players’ as props
, given the fact they are fetched at Child1.jsx
.
class Child2 extends Component { constructor(props) { super(props); this.state = { players:[] }; } handlePlayers = () => { // do something with players here }; handleChangePlayers = () => { this.props.onDeselectPlayers(); }; render() { return ( ... <Button handleClick={() => this.handlePlayers()}> <Button handleClick={() => this.handleChangePlayers()}> ... ); }
I know I can achieve this by having a callback to App.jsx
at Child1.jsx
, so I can pass players as props to Child2.jsx
, but how so?
Advertisement
Answer
You can keep the players
state on the Parent of both Child components. This way, you can pass it down as props to the relevant components. Refer to my comments on the code for insight
function App(){ const [players, setPlayers] = React.useState(); // single source of truth for players return ( <React.Fragment> <Child1 setPlayers={setPlayers}/> // pass state setter to Child1 where you perform the xhr to fetch players <Child2 players={players}/> // pass players down as props to Child2 </React.Fragment> ) } class Child1 extends React.Component{ componentDidMount(){ this.getPlayers(); // sample fetching of players } getPlayers() { this.props.setPlayers([ // set players state which resides on the parent component "App" "foo", "bar" ]); } render() {return "Child1"} } class Child2 extends React.Component{ componentDidUpdate(){ // this.props.players contains updated players console.log(`Child2 players`, this.props.players); } render() {return "Child2"} } ReactDOM.render(<App/>, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script> <div id="root"></div>