Я пытаюсь инициализировать три функции как состояние в конструкторе, чтобы получить значения из этих функций и иметь эти значения в состоянии перед первым рендерингом. Однако одна из функций имеет переменную, зависящую от значения предыдущей функции, и поэтому я получаю сообщение об ошибке.

Как бы я исправить эту проблему? Код ниже!

Файл app.js

import React from "react";
import Calendar from "./Calendar"

function App() {
    return (
        <div>
            <Calendar />
        </div>    

    )
}

export default App;

Файл Calendar.js

import React from "react";


class Calendar extends React.Component {
    constructor() {
        super();

    this.state = {
        //curLastDate() is dependent on lastDayOfMonth()
        lastDayOfMonth: this.storeLastDate(),
        currentLastDate: this.curLastDate()
    }
}
    /*
    Stores the last date of all months of the current year
    Format: [ ["Thu", "Jan", "31", "2019]... ]
    */
    storeLastDate() {
            let date, 
                string, 
                lastDate, 
                list = [];

            date = new Date();

            for (let i = 1; i < 13; i++) {

                lastDate = new Date(date.getFullYear(), i, 0);
                string = lastDate.toDateString().split(" ");
                list.push(string);
            }

            return list;
    }  

/*
Finds the matching month of current date
*/
curLastDate() {

    for (let i = 0; i < this.state.lastDayOfMonth.length; i++) {
        if (this.state.currentDate[1] === this.state.lastDayOfMonth[i][1]) {
            console.log(this.state.lastDayOfMonth[i][1]);
            return this.state.lastDayOfMonth[i][1];
        }
    }
}

render() {
    return (
        null
        )
    }

}
export default Calendar;

В конечном счете, я хочу инициализировать значения, которые я получаю из функций, в состояние до того, как React получит свой первый рендер. Спасибо за помощь в продвижении!

0
Elijah.S 29 Май 2019 в 23:12

2 ответа

Лучший ответ

Установите значения в componentDidMount и передайте обратный вызов .setState().

constructor() {
  super();
  this.state = {
    lastDayOfMonth: [],
    currentLastDate: [],
    currentDate: new Date(),
  };
}

storeLastDate = () => {
  let date,
    string,
    lastDate,
    list = [];

  date = new Date();

  for (let i = 1; i < 13; i++) {
    lastDate = new Date(date.getFullYear(), i, 0);
    string = lastDate.toDateString().split(' ');
    list.push(string);
  }

  return list;
}

 /*
  Finds the matching month of current date
*/
curLastDate = () => {
  for (let i = 0; i < this.state.lastDayOfMonth.length; i++) {
    if (this.state.currentDate[1] === this.state.lastDayOfMonth[i][1]) {
      console.log(this.state.lastDayOfMonth[i][1]);
      return this.state.lastDayOfMonth[i][1];
    }
  }
}

componentDidMount = () => {

  const lastDayOfMonth = this.storeLastDate();

  this.setState({
    lastDayOfMonth: lastDayOfMonth
  }, () => {
     this.setState({ currentLastDate: this.curLastDate() });
   }) // curLastDate as callback, which will be executed after setting state
}
1
Junius L. 29 Май 2019 в 22:05

Попробуйте что-то вроде этого:

Если вы снова используете свою функцию curLastDate, просто передайте lastDayOfMonth

import React, {useState, useEffect} from "react";

function Calendar() {
    //curLastDate() is dependent on lastDayOfMonth()
    const [lastDayOfMonth, setLastDayOfMonth] = useState();
    const [currentLastDate, setCurrentLastDate] = useState();

    useEffect(async () => {
        const list = await storeLastDate();
        setLastDayOfMonth(list);
        const curLastDateRet = curLastDate(list);
        setCurrentLastDate(curLastDateRet);
    }, []);

    const storeLastDate = () => {
        return new Promise((resolve, reject) => {
            let date,
                string,
                lastDate,
                list = [];

            date = new Date();

            for (let i = 1; i < 13; i++) {

                lastDate = new Date(date.getFullYear(), i, 0);
                string = lastDate.toDateString().split(" ");
                list.push(string);
            }
            resolve(list);
        });
    }

    /*
    Finds the matching month of current date
    */
    const curLastDate = lastDayOfMonth => {
        for (let i = 0; i < lastDayOfMonth.length; i++) {
            if (this.state.currentDate[1] === lastDayOfMonth[i][1]) {
                console.log(lastDayOfMonth[i][1]);
                return lastDayOfMonth[i][1];
            }
        }
    }

    return (
        <></>// some content here
    )

}
export default Calendar;

0
Marcello Silva 29 Май 2019 в 20:40