Reputation: 312
I'm wondering what is the best way of doing this.
I have 3 components, App, String and Note. Before I was creating Note elements in App like this:
<Note
state={this.state.btnStates[i]}
onClick={() => this.handleClick(i)}
/>
and it was working like charm (handleClick is of course in the most parent component - App)
but now I want to transfer note creation to the String component, I thought that would be easy but what I thought to work just doesn't. I'm doing it like this: in App component i render String:
<String
btnStates={this.state.btnStates}
onClick={(i) => this.handleClick(i)}
></String>
in String component:
for (var i = 0; i < stringLength; i++) {
notes.push(
<Note
key={i}
onClick={keyFromNoteCall => this.props.onClick(keyFromNoteCall)}
state={this.props.btnStates[i]}
></Note>
);
}
and in Note component:
<input
type="button"
className={this.getClassName(this.props.state)}
onClick={() => this.props.onClick(this.props.key)}
value={this.props.value}
disabled={this.isDisabled()}
/>
What is the React way of doing such things? I need the logic to be handled in the App, but I would like move the rendering of Notes in a loop to another component.
*UPDATE: it turned out the problem was "key" property as it can't be accessed with {this.props.key}
I created another property "id" for that purpose and it works. I have another problem now, that even after binding in App constructor, this
logged in handleClick function doesn't show App component but rather the Note itself :/
Upvotes: 0
Views: 127
Reputation: 15
Without using a state handler like Context or Redux, the React way of doing it is passing the function as props.
App.js
<String
btnStates={this.state.btnStates}
handleClick={this.handleClick}
/>
String component
for (var i = 0; i < stringLength; i++) {
notes.push(
<Note
key={i}
handleClick={this.props.handleClick}
state={this.props.btnStates[i]}
></Note>
);
}
Note component
<input
type="button"
className={this.getClassName(this.props.state)}
onClick={() => this.props.handleClick(this.props.key)}
value={this.props.value}
disabled={this.isDisabled()}
/>
Also I recommend you that in your String component you do a .map() instead of a for loop.
notes.map(note =>
<Note key={note.id}
handleClick={this.props.handleClick}
state={note.btnStates}
)
This way you would have to refactor to have IDs on your notes but you should do it because using indexes as keys can cause problems.
Upvotes: 1
Reputation: 120
If I understood you correctly, you should change onClick in App to this and that should do it.
<String
btnStates={this.state.btnStates}
onClick={this.handleClick}
/>
Upvotes: 0