Реагировать - как изменить несколько начальных состояний на основе свойств - PullRequest
0 голосов
/ 11 июля 2020

Я новичок ie в React. Я задал вопрос о своем коде. Я не могу инициализировать состояние на основе реквизита. Например, я могу получить значение jsonData (в классе NCMenuItems), но когда я пытаюсь инициализировать другие состояния, такие как группы, showpin, direction, isCollapsible на основе значения jsonData, React всегда выдает мне ошибку, говоря, что эти состояния равны нулю.

Кроме того, я обнаружил еще одну проблему: console.log в render() в классе NCMenuItems всегда печатается дважды, почему? Большое вам спасибо.

Вот мой код:

NCMenuItems class

import React, {Component} from 'react';
import NCMenuItem from '../MenuComponent/NCMenuItem';

class NCMenuItems extends Component {
state = {
    jsonData: this.props.jSONObj,
    showpin: false,
    direction: false,
    isCollapsible: false,
    cssFilePath: '',
    groups: null
};

static getDerivedStateFromProps(props, state){
    return {
        showpin: this.state.jsonData.showpin === '1'? true:false,
        direction: this.state.jsonData.direction === '1'? true:false,
        isCollapsible: this.state.jsonData.isCollapsible === '1'? true:false,
        cssFilePath: this.state.jsonData.cssFilePath,
        groups: this.state.jsonData.groups
    }
}


render() {
    console.log('From NCMenuItems this.props.jSONObj',this.props.jSONObj);
    console.log('From NCMenuItems this.state.jsonData',this.state.jsonData);
    console.log('From NCMenuItems this.state.groups',this.state.groups);
    console.log('From NCMenuItems this.state.jsonData.groups',this.state.jsonData.groups);
    return (
    <div>
        <ul id="nc-menu-ul" showpin direction isCollapsible cssFilePath={this.state.isCollapsible}>
            {/* <NCMenuItem groups={this.state.groups}/> */}
        </ul>
    </div>
    );
}
}

export default NCMenuItems;

В приложении. js

import React, { Component } from 'react';
import NCMenuItems from './MenuComponent/NCMenuItems';

class App extends Component {
constructor(props) {
super(props);
this.state = {
  deserializedJSONObj: {
    nc_menu_parameters: {
      showPin: 1,
      direction: 1,
      isCollapsible: 1,
      cssFilePath: ""
    },
    nc_menu_groups: [
      {
        label: "Project",
        nc_menu_entries: [
          { entryLabel: "Overview", entryLink: "/Details", isClickable: 1 },
          { entryLabel: "Comments", entryLink: "/Comments", isClickable: 1 },
          { entryLabel: "Activity", entryLink: "/Activity", isClickable: 1 },
          { entryLabel: "Multiplier", entryLink: "/Multiplier", isClickable: 1 }
        ]
      },
      {
        label: "Heaters",
        nc_menu_entries: [
          {
            entryLabel: "In design",
            entryLink: "/InDesignParts",
            isClickable: 1
          },
          { entryLabel: "Parts", entryLink: "/InDesignParts", isClickable: 1 },
          {
            entryLabel: "Pricing",
            entryLink: "/InDesignPricing",
            isClickable: 1
          },
          {
            entryLabel: "Documents",
            entryLink: "/InDesignDocument",
            isClickable: 1
          }
        ]
      }
    ]
  }
};
}


 render() {
console.log('FROM App.js', this.state.deserializedJSONObj);
return (
  <div>
    <NCMenuItems jSONObj={this.state.deserializedJSONObj} />{/* pass the JSON object as props to NCMenuItems*/}
    <h1>Test the nc_menu!</h1>
  </div>
);
}
}

export default App;

1 Ответ

0 голосов
/ 11 июля 2020

Рендеринг запускается дважды, потому что первый рендеринг происходит при монтировании, второй повторный рендеринг происходит при вызове getDerivedStateFromProps, который снова устанавливает состояние и запускает повторный рендеринг.

Что касается вашего вопроса, вам нужно смотреть на props.jsonData, а не на state.jsonData. Это связано с тем, что операция установки состояния - asyn c, и состояние еще не обновлялось при вызове метода.

Вам не нужны оба этих метода, вы можете вычислить свое состояние в конструкторе . Уничтожьте JSONObj из props и создайте состояние с вычислениями, которые вы уже выполняете в getDerivedStateFromProps - с небольшим изменением. Вам нужно посмотреть значения JSONObj из props, а не state.

class NCMenuItems extends Component {
  constructor(props) {
    super(props);
    const {JSONObj} = props;
    this.state = {
     jsonData: JSONObj,
     showPin: JSONObj.showPin === '1',
     direction: JSONObj.direction === '1',
     isCollapsible: JSONObj.isCollapsible === '1',
     cssFilePath: JSONObj.cssFilePath,
     groups: JSONObj.groups

...etc
  }
}

Вычислить все данные на основе полученных вами реквизитов, а затем установить эти значения в состояние.

Вам также не нужен ? true : false, потому что условие неявно истинно или ложно.

Это:

showpin: this.state.jsonData.showpin === '1'? true:false,

is равно:

showpin: this.state.jsonData.showpin === '1'

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...