Reagire cercando di assegnare oggetti di scena alla variabile di stato non funziona
Sto cercando di assegnare gli oggetti di scena che ottengo dal componente genitore e di assegnarli allo stato nel componente figlio (poiché voglio manipolare i dati degli oggetti di scena, lo assegno prima allo stato).
Quando registro la variabile di stato risulta come un array vuoto, ma quando creo una nuova variabile nel rendering e le assegno oggetti di scena e la registro. Mostra i dati di cui ho bisogno. Inoltre, quando eseguo il log this.propsposso sicuramente vedere che gli oggetti di scena contengono i dati di cui ho bisogno.
Ho assegnato oggetti di scena da dichiarare un paio di volte in precedenza, quindi non sono sicuro di cosa sia così diverso questa volta da non funzionare.
Componente genitore in cui passo gli oggetti di scena al bambino:
<ShowAvailableTimeslots onClick={this.getSelectedTimeslot} allTimeSlots={this.state.AvailabletimeSlots} />
Componente figlio in cui cerco di assegnare oggetti di scena allo stato:
class ShowAvailableTimeslots extends Component {
constructor(props) {
super(props)
this.state = {
sliceEnd: 5,
sliceStart:0,
selectedSlotValue: "",
timeSlotArr: this.props.allTimeSlots,
// timeSlotSlice: timeSlotArr.slice(this.state.sliceStart, this.state.sliceEnd)
}
}
handleTimeSlotClick = (timeSlot) => {
this.setState({ selectedSlotValue: timeSlot }, () => {
this.props.onClick(this.state.selectedSlotValue)
console.log('time slot value', timeSlot)
});
}
previousSlots =()=>{
var test;
}
forwordSlots =()=>{
var test;
}
render() {
var timeSlotArrRender = this.props.allTimeSlots;
return (
<React.Fragment>
{console.log("state", this.state.timeSlotArr)} // --> doesn't show data
{console.log("props", this.props)} // --> does show data
{console.log("render variable", timeSlotArrRender )} // --> does show data
<button className="button btn" onClick={() => this.previousSlots()} disabled={this.state.sliceStart === 0}>left</button>
{/* {this.state.timeSlotArr.map(timeSlot => <a className="timeslot btn " key={timeSlot} value={timeSlot} onClick={() => this.handleTimeSlotClick(timeSlot)}>{timeSlot}</a>)
} */}
<button className="button btn">right</button>
</React.Fragment>
)
}
}
export default ShowAvailableTimeslots
Risposte
il costruttore viene chiamato quando inizia il ciclo di vita del componente. Stai passando this.state.AvailabletimeSlots dal genitore ea quel punto il costruttore è già stato chiamato e l'assegnazione per timeSlotArr è già stata eseguita, quindi
timeSlotArr: this.props.allTimeSlots // will not work
Devi ottenere l'aiuto dei metodi del ciclo di vita o dei ganci
componentWillReceiveProps(nextProps){
this.setState({timeSlotArr: nextProps.allTimeSlots })
}
In base alle nuove modifiche che devi usare
static getDerivedStateFromProps(nextProps, prevState){
return {
timeSlotArr: nextProps.allTimeSlots
};
}
Lo faccio funzionare bene. https://jsfiddle.net/85zc4Lxb/
class App extends React.Component {
render() {
return (<Child passing="I am being passed to child" />);
}
}
class Child extends React.Component {
constructor(props) {
super(props)
this.state = {
passedProp: this.props.passing,
}
}
render() {
return (
<React.Fragment>
<button>{this.state.passedProp}</button>
</React.Fragment>
)
}
}
ReactDOM.render(
<App />,
document.getElementById('container')
);
Provo a ricreare lo scenario e funziona, prova a salvare di nuovo tutti i tuoi file e poi controlla
componente dei genitori
import React, { Component } from "react";
import TestOne from "./Components/TestOne/TestOne";
export class App extends Component {
state = {
x: "x data",
y: "y data",
};
render() {
return (
<div>
<TestOne x={this.state.x} allTimeSlots={this.state.y}/>
</div>
);
}
}
export default App;
Componente figlio
import React, { Component } from "react";
export class TestOne extends Component {
constructor(props) {
super(props);
this.state = {
sliceEnd: 5,
sliceStart: 0,
selectedSlotValue: "",
timeSlotArr: this.props.x,
};
}
render() {
var timeSlotArrRender = this.props.allTimeSlots;
return (
<React.Fragment>
{console.log("state", this.state.timeSlotArr)}
{console.log("props", this.props)}
{console.log("render variable", timeSlotArrRender)}
<button className="button btn">right</button>
</React.Fragment>
);
}
}
export default TestOne;
Risultato: