简体   繁体   中英

How do you change state of a react component from a different component?

I am trying to understand how to pass props to components in react. I am new to react and I have been struggling to understand the fundamentals of state.

I would like a button to display an overlay and populate the "content" of that overlay with some arbitrary text for now.

I am trying to use a prop called doWeDisplay as variable to hold a css value of "none" or "absolute" (to hide and show the component) and a prop called "content" for the content of the overlay.

Here is my code, could someone please point me in the right direction. I need that eureka moment for it to click in place and my head is all over the place trying to get this.

app.js

import React from 'react';
import Overlay from './components/overlay';
import Header from './components/header';
import Body from './components/body';
import Footer from './components/footer';
import './App.css';

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
    };
  }

  render() {
    console.log("App props", this.props)
    return (
      <div className="App">
        <Overlay />
        <Header />
        <Body content={ this.props.appContent } />
        <Footer />
      </div>
    );
  }
}

export default App;

body.js

import React from 'react';
import './body.css';
import Overlay from './overlay'

class Body extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      doWeDisplay : "absolute",
      content : "Go on"
    };
  }

  render() {
    function handleClick(e) {
      console.log("Click")
      Overlay.setState((state, props) => ({
        doWeDisplay : "absolute",
        content : "Go on"
      }))
    }
    console.log("Body props ", this.props);
    return (
      <div className="App-Body">
        <p>Here is the body of the page.</p>
        <button onClick={ handleClick }>Click me</button>
      </div>
    );
  }
}

export default Body

overlay.js

import React from 'react';
import './overlay.css';

class Overlay extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      doWeDisplay : props.doWeDisplay,
      content : props.doWeDisplay
    };
  }

  render() {
    console.log("Overlay props " , this.props)
    return (
      <div className="App-Overlay" style={{ display: this.state.doWeDisplay }}>
        { this.state.content }
      </div>
    );
  }
}

export default Overlay

When you have sibling components that can change other's state, you will need to handle that state in the parent component (in your case it is App ).

So the handleClick() function should be in the parent component, and the state itself of the variables doWeDisplay and content should be in App as well.

Then, you can pass that function to Body as a prop, so you could trigger it on click within the Body component. I called that prop clickFunc in my example.

Finally, the last thing you will need is to pass the current state to Overlay as props, so I passed the doWeDisplay and content as different props, that gets the value from App 's state.

It should look something like this:

app.js

import React from 'react';
import Overlay from './components/overlay';
import Header from './components/header';
import Body from './components/body';
import Footer from './components/footer';
import './App.css';

    class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      doWeDisplay: "absolute",
      content: "Go on"
    };
  }

  handleClick = () => {
    console.log("Click");
    this.setState({
      doWeDisplay: "absolute",
      content: "Go on CHANGED!"
    });
  };

  render() {
    console.log("App props", this.props);
    return (
      <div className="App">
        <Overlay
          doWeDisplay={this.state.doWeDisplay}
          content={this.state.content}
        />
        <Body clickFunc={this.handleClick} content={this.props.appContent} />
      </div>
    );
  }
}

export default App;

body.js

import React from 'react';
import './body.css';
import Overlay from './overlay'

class Body extends React.Component {
  render() {
    console.log("Body props ", this.props);
    return (
      <div className="App-Body">
        <p>Here is the body of the page.</p>
        <button onClick={() => this.props.clickFunc()}>Click me</button>
      </div>
    );
  }
}

export default Body

overlay.js

import React from 'react';
import './overlay.css';

class Overlay extends React.Component {
  render() {
    console.log("Overlay props ", this.props);
    return (
      <div className="App-Overlay" style={{ display: this.props.doWeDisplay }}>
        {this.props.content}
      </div>
    );
  }
}

export default Overlay

Here's codesandbox

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM