[英]React - How can I change multiple initial states based on the props
我是 React 的新手。 我想出了一個關於我的代碼的問題。 我無法根據道具初始化 state。 例如,我可以獲得 jsonData(在 NCMenuItems 類中)值,但是當我嘗試根據jsonData
值初始化其他狀態(如組、showpin、direction、 isCollapsible
)時,React 總是給我一個錯誤,說這些狀態是 null。
另外,我發現另一個問題,NCMenuItems class 中的render()
中的console.log
總是打印兩次,這是為什么呢? 太感謝了。
這是我的代碼:
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;
在 App.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;
渲染被觸發兩次,因為第一次渲染發生在掛載時,第二次重新渲染發生在調用 getDerivedStateFromProps 時 - 再次設置getDerivedStateFromProps
並觸發重新渲染。
關於您的問題,您需要查看props.jsonData
,而不是state.jsonData
。 這是因為 state 設置操作是異步的,調用該方法時 state 尚未更新。
你不需要這兩種方法,你可以在構造函數中計算你的 state 。 從 props 中解構 JSONObj,並使用您已經在 getDerivedStateFromProps 中進行的計算創建getDerivedStateFromProps
- 稍作更改。 您需要查看來自props
的JSONObj
的值,而不是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
}
}
根據收到的道具計算所有數據,然后在 state 中設置這些值。
你也不需要? true: false
? true: false
,因為條件隱含地為真或假。
這個:
showpin: this.state.jsonData.showpin === '1'? true:false,
等於:
showpin: this.state.jsonData.showpin === '1'
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.