I followed a tutorial and came out with this https://jsbin.com/foxoxejilu/1/edit?js,output using react.js.
I'm confused with the props and state. In the save
method of Note component
, what does this line do
this.props.onChange(this.refs.newText.value, this.props.id)
And I don't see onChange and onRemove function elsewhere in the code, is that a pre-build function of react? how does react know the DOM got changed or removed?
We could summarise what is happening like this:
A Parent (Board
) packs her Child (Note
) a bag (props
) and puts a mobile phone (onChange
) and says: if you want to tell me something just text me the message. Then after some time the Child thinks "let's text my parent" so the Child takes the phone out of his properties and texts the Parent: this.props.onChange("Thank you for sandwiches")
. The Parent, then receives the message and saves it into her notebook (state
): this.setState({notes})
This is where the child receives the properties (props):
<Note key={note.id}
id={note.id}
onChange={this.update}
onRemove={this.remove}>
{note.note}
</Note>
When the above finds its way to the render()
method of the Board
component (via {this.state.notes.map(this.eachNote)}
, it's like Board
saying,
Note
component and lets give it some properties (props)". onChange
and when it is invoked by the Note
later, let's execute my own method called update
"onChange
we could call it whatever we want, for example <Note ... fromParentWithLove={this.update}> ... </Note>
, but let's call it onChange
so that it is easier to follow our intentions."Then, we can move to the child component - Note
. Note
is saying to itself:
save
method:" <button onClick={this.save}>Save</button>
save
method let's invoke the onChange
function given to me by my parent Board
via props": this.props.onChange(this.refs.newText.value, this.props.id)
"For reference, below is the code copied from the JSBin:
var Note = React.createClass({
getInitialState(){
return {editing: false}
},
edit() {
this.setState({editing: true})
},
save() {
this.props.onChange(this.refs.newText.value, this.props.id)
this.setState({editing: false})
},
remove() {
this.props.onRemove(this.props.id)
},
renderForm() {
return(
<div className="note">
<textarea ref="newText"></textarea>
<button onClick={this.save}>Save</button>
</div>
)
},
renderDisplay() {
return(
<div className="note">
<p>{this.props.children}</p>
<span>
<button onClick={this.edit}>Edit</button>
<button onClick={this.remove}>X</button>
</span>
</div>
)
},
render() {
return (this.state.editing) ? this.renderForm() : this.renderDisplay()
}
})
var Board = React.createClass({
propTypes: {
count: function(props, propName) {
if(typeof props[propName] !== 'number'){
return new Error('the count must be a number')
}
}
},
getInitialState() {
return {
notes: [
{id:1, note:'Call boook'},
{id:2, note:'Buy Something'},
{id:3, note:'Wash Clothes'},
{id:4, note:'Go Jogging'}
]
}
},
update(newText, id){
var notes = this.state.notes.map(
note => (note.id !== id) ?
note:
{
...note,
note:newText
}
)
this.setState({notes})
},
remove(id){
var notes = this.state.notes.filter(note => note.id !== id)
this.setState({notes})
},
eachNote(note) {
return (<Note key={note.id}
id={note.id}
onChange={this.update}
onRemove={this.remove}>
{note.note}
</Note>)
},
render() {
return (<div className='board'>
{this.state.notes.map(this.eachNote)}
</div>)
}
})
ReactDOM.render(<Board count={10}> </Board>,
document.getElementById('react-container'))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With