1

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.

3
  • is this.handleStateChange = this.handleStateChange.bind.bind(this) copy paste error? Commented Jun 6, 2018 at 9:36
  • It's a typo, I'm modyfing and editing the post Commented Jun 6, 2018 at 9:40
  • 1
    you dont need this.props.handleStateChange= this.props.handleStateChange.bind(this). just invoke this.props.handleStateChange(newWindow) Commented Jun 6, 2018 at 9:52

3 Answers 3

1

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
  ]
})
Sign up to request clarification or add additional context in comments.

2 Comments

I changed it but now i get TypeError: Cannot read property 'bind' of undefined
In the Landing component you don't have to bind this. Just assign onClick={this.props.handleStateChange}
0

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.

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.