简体   繁体   中英

Modifying parent array from child component - React

I'm building a React app, I need to store the handlers for all windows I open from the app (ye it's a bit weird but it's what I have to do). Before using React I was storing the windows on a global array atached to the parent window (I know JS global variables are a really bad practice but it was specified in the project to do so).

I would like not to use Redux and try to solve this with only React.

In the new React app I have this array declared on the state of the App component, and a method to manipulate the stae which I'm passing as a prop to the child component:

class App extends Component {

  constructor(props) {
    super(props);
    this.state = { name: 'Desktop', openedWindows: [] };        

    this.handleStateChange = this.handleStateChange.bind(this)
  }  

   handleStateChange(param) {
     this.setState({
     openedWindows: [
       ...this.state.openedWindows,
       param
     ]
})

}

  render() {   
    const themes = ['#2c2f33', 'teal']
    const backgroundColor = themes[0]          

    return (
      this.state.name === 'Desktop' ?
      <div className='App'>
        <Header backgroundColor = {backgroundColor} />
        <Landing backgroundColor = {backgroundColor} 
          handleStateChange = {this.handleStateChange} />
        <Footer backgroundColor = {backgroundColor}/>
      </div>
      :
      <div className='App'>
        <Header backgroundColor = {backgroundColor} />
      </div>
    )
  }
}

export default App;

This is the child component trying to change the state:

class Landing extends Component {
    handleOpenWindow = () => {     
        let newWindow = window.open('', '_blank')
        this.props.handleStateChange= this.props.handleStateChange.bind(this)
    }

    render () {
        const { backgroundColor } = this.props
        return (            
            <div className='landing'>
                <button className='btn' 
                    onClick={this.handleOpenWindow}
                    style={{backgroundColor}}
                >Abrir Editor
                </button>

            </div>
        )
    }
}

export default Landing

I get a TypeError: Bind must be called on a function

I've tried different approaches on the call of the function, but I can't get this to work. Don't know what I'm doing wrong or if this is possible without using Redux.

Thanks in advice.

There are 2 issues:

There is a typo in the constructor: this.handleStateChange.bind.bind(this) that is one .bind too much.

In handleStateChange(param) the state update is wrong: It should be

this.setState({
  openedWindows: [
    ...this.state.openedWindows,
    param
  ]
})

You have to make changes in the child component's handleOpenWindow() like,

    handleOpenWindow = () => {     
        let newWindow = window.open('', '_blank')
        this.props.handleStateChange(newWindow);
    }

You have to pass the opened window object back to your parent as a param and you dont need to bind it here. Rest looks good.

Parent Component

//create an array in state.

`constructor(props){
     this.state={
         name:[]
     } 
 }`

now create a function which accepts an array as an argument and setState

handleChange=(value)=>{
    this.setState({name:value});
}

Now pass the function as a prop to the child component and then you can pass the value(argument) from the child which would eventually do a setState in the parent component

Child component

`setData=()=>{
    let name=[1,2,3,4];
    this.props.handleChange(name); 
 }`

make sure you pass the function to the child component. This will help you set the state in a parent from a child component.

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