Reagire cercando di assegnare oggetti di scena alla variabile di stato non funziona

Aug 25 2020

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

1 Anup Aug 25 2020 at 00:01

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
  };
}
RahulMaddineni Aug 24 2020 at 23:17

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')
);

Hamza Aug 24 2020 at 23:28

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: