I'm still pretty new with ReactJS and now I ran into something which confuses me totally.
I've created a bunch of components which render a Bootstrap modal. Furthermore I fetch initial state parameters from the sever through the componentDidMount function. My component structure looks something like this:
<App>
<Modal Lauch Button />
<Modal>
<Modal Header />
<Modal Body /> <-- here's the problem
</Modal>
</App>
and my initial state array is of the form (of course JSON encoded):
array:5 [▼
...
...
"private" => true
"files" => array:2 [▼
1 => array:7 [▼
"id" => 0
"route" => "some route"
...
...
]
2 => array:7 [▼
"id" => 1
"route" => "some other route"
...
...
]
]
]
and my (minified) React application like this:
<script type="text/babel">
var L5fmModalBody = React.createClass({
render: function() {
return(
<Modal.Body>
<Grid fluid={true}>
<Row>
{
this.props.files.map(function (file) {
return <L5fmModalBodyFileContent id={file.id} route = {file.route} / >
})
}
</Row>
</Grid>
</Modal.Body>
);
}
});
var L5fmModalBodyFileContent = React.createClass({
render : function() {
return(
<Col xs={6} md={4} className="img-row">
<div className="thumbnail thumbnail-img">
<img key={this.props.id} src={this.props.route} />
</div>
</Col>
);
}
});
var L5fmModal = React.createClass({
getInitialState : function() {
return {
data : []
};
},
componentDidMount: function() {
$.ajax({
url: 'L5fm/setInitialState',
dataType: 'json',
cache: false,
success: function(data) {
this.setState({data: data});
console.log(data);
console.log(this.state.data);
}.bind(this),
error: function(xhr, status, err) {
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
render: function() {
return(
<Modal {...this.props} bsSize="large" aria-labelledby="contained-modal-title-lg">
<Modal.Header closeButton>
<div className="header-button-group">
some buttons
</div>
</Modal.Header>
<L5fmModalBody files={this.state.data.files} />
</Modal>
);
}
});
var App = React.createClass({
getInitialState: function() {
return { lgShow: false };
},
render: function() {
let lgClose = () => this.setState({ lgShow: false });
return (
<Button bsStyle="primary" onClick={()=>this.setState({ lgShow: true })}>
Launch large demo modal
</Button>
<L5fmModal show={this.state.lgShow} onHide={lgClose} />
);
}
});
ReactDOM.render(<App />, document.getElementById("modal"));
</script>
Whenever I run the application I get following error:
L5fmModalBody_renderTypeError: this.props.files.map is not a function. (In 'this.props.files.map', 'this.props.files.map' is undefined)
If I console.log(this.state.data.files) in my <Modal> component, it also shows that this.state.data.files is undefined? Obviously I have not understood what is going on. I've also tried to fetch data with componentWillMount but this did not help either. What am I doing wrong?
Thanks!
UPDATE
I think I got a step further. The actual issue is not that this.set,state is null at the start, because after componentDidMount is called and the "new" states are set, the UI gets rendered again. Furthermore I found out that JSON apparently handles assoziative arrays as objects and I believe that I can't call map on an object.
Any ideas?
this.state.datalog?console.log(this.state.data)into the render function of<L5fmModal>I get[] (0)as log output. I guess that is just the predefined emptydataarray. But how can I fetch data from the server and THEN render the whole application?