Reputation: 11040
I have a redux store with a state called "Pets" which stores an array of the following:
[{"id"2,"name":"Cat"},
{"id":3,"name":"Dog"},
{"id":4,"name":"Fish"}
]
In my component, I map the states like this: (I'm using redux forms and react-bootstrap-table)
class PetsPage extends Component {
constructor(props) {
super(props);
this.state =({
selected:[]
});
this.showRow = this.showRow.bind(this);
}
componentWillMount() {
this.props.fetchPets();
}
render() {
const {
handleSubmit,
previousPage,
pets
} = this.props
if (!pets){
return (
<div className="container">
<div> Loading...</div>
</div>
);
}
return (
<div className="container">
<BootstrapTable
data={pets}
search={true}
striped={true}
hover={true}
condensed={true}
selectRow={selectRowProp}>
<TableHeaderColumn dataField="id" isKey={true}>Pet #</TableHeaderColumn>
<TableHeaderColumn dataField="name">Company</TableHeaderColumn>
</BootstrapTable>
<p> Currently Chosen: <span> id: {this.state.selected}</span> </p>
<div className="btn-group">
<button type="button" onClick={previousPage} className="btn btn-success btn-lg"><i/> Previous</button>
<button type="submit" className="btn btn-success btn-lg">Next</button>
</div>
</div>
</form>
)
}
}
function mapStateToProps(state) {
return { pets: state.pets.all };
}
export default reduxForm({
form: 'wizard',
fields,
destroyOnUnmount: false,
validate
}, mapStateToProps, actions)(PetsPage)
So far, everything WORKS. My problem arises when I call the pets prop like this:
<p> Currently Chosen: {pets[2].name}</p>
I keep getting this error:
TypeError: pets[2] is undefined
Ideally I want to be able to call the name of the pet by the ID which is provided by the "selected" state.
EDIT --- I noticed the code actually WORKS if I were to go to another page and come back to this page. This is kind of confusing because I thought having the ...loading container would prevent this from happening.
Upvotes: 2
Views: 180
Reputation: 11040
Ok, I just figured it out. Following xiaofan2406's suggestion, I literally have to put
if(this.props.pets[0])
Because
if(this.props.pets)
will always be true.
Upvotes: 0
Reputation: 3310
How do you obtain the initial state of pets
? were those retrieved asynchronously? (which i suspect it is)
When your BootstrapTable
initially load, the async call was not complete, pets
was still undefined, hence the error. Then when you go to another page, and come back to this page, your async call was finished, pets
is now an array, and it works.
If I am right so far, add something like this in your BootstrapTable
:
if(this.props.pets) {
<p> Currently Chosen: {pets[2].name}</p>
... // render your pets props within the
} else {
// render some loading indicator
}
Edit: if your pets was initialized as an empty array, check the length of the pets instead of the truthy value
Upvotes: 2
Reputation: 4713
Shouldn't you be doing this.props.pets[2] ? Or this.state.pets[2] ? Unsure exactly what's happening but I don't think pets[2] on it's own would ever be anything. If that doesn't help can you post some more of your code?
Upvotes: 0