Reputation: 125
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.
Upvotes: 1
Views: 1031
Reputation: 1146
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.
Upvotes: 0
Reputation: 5669
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.
Upvotes: 0
Reputation: 5956
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
]
})
Upvotes: 1