将状态作为道具传递给子组件不起作用
Posted
技术标签:
【中文标题】将状态作为道具传递给子组件不起作用【英文标题】:Passing state into child component as props not working 【发布时间】:2017-11-19 18:34:58 【问题描述】:我正在尝试使用 React 和 React Router 构建示例 CRUD 应用程序,但我无法弄清楚为什么状态没有按照我期望的方式传递到子组件中。当我点击edit
路由时,它会呈现Edit
组件,该组件从数据库中获取我想要的小猫并将其信息发送到一个表单组件,该组件用于编辑现有的小猫或添加新的小猫。
这是编辑组件:
import React, Component from 'react';
import axios from 'axios';
import match from 'react-router-dom';
import Form from './Form';
export default class Edit extends Component
constructor(props)
super(props)
this.state =
componentDidMount()
axios.get(`/updateKitten/$this.props.match.params.id`)
.then(res =>
const kitten = res.data
this.setState( kitten )
console.log(this.state.kitten.name) //Sammy, or something
)
.catch(err => console.log(err))
render()
return (
<Form
name=this.state.kitten.name // throws error or undefined
description=this.state.kitten.description //throws error or undefined
route=this.props.match.params.id
/>
)
Edit 组件将名称、描述和路由传递给此 Form 组件:
import React, Component from 'react';
import axios from 'axios';
export default class Add extends Component
constructor(props)
super(props)
this.state = name: this.props.name, description: this.props.description
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
handleChange(e)
const name = e.target.name;
const value = e.target.value;
this.setState(
[name]: value
);
handleSubmit(e)
axios.post(`/addKitten/$this.props.route`, this.state)
.then(this.setState( name: '', description: '' ))
e.preventDefault();
render()
return (
<form onSubmit=this.handleSubmit>
<label>Name</label>
<input type='text' name="name" value=this.state.name
onChange=this.handleChange/>
<label>Description</label>
<input type='text' name="description" value=this.state.description
onChange=this.handleChange/>
<input type='submit' value='Submit' />
</form>
)
我收到以下错误:
bundle.js:28950 Uncaught TypeError: Cannot read property 'name' of undefined
试图将该信息作为道具发送到Form
组件。
我做错了什么?
【问题讨论】:
【参考方案1】:两件事,
首先:在您的编辑组件中,您尚未初始化小猫状态,您正在根据 API 结果进行设置。然而,componentDidMount 在组件被调用之后被调用,因此 DOM 被渲染了一次,并且第一次它没有找到任何值 this.state.kitten.name
或 this.state.kitten.description
。
只有在 API 成功后,您才能设置小猫状态。因此,只需在渲染时进行检查。
第二:console.log(this.state.kitten.name)
在 setState
函数之后。但是setState is asynchronous
。看到这个问题:
Change state on click react js
因此您需要在 setState 回调中指定 console.log
你的代码看起来像
export default class Edit extends Component
constructor(props)
super(props)
this.state =
componentDidMount()
axios.get(`/updateKitten/$this.props.match.params.id`)
.then(res =>
const kitten = res.data
this.setState( kitten . function()
console.log(this.state.kitten.name) //Sammy, or something
)
)
.catch(err => console.log(err))
render()
return (
<Form
name=this.state.kitten.name || ''
description=this.state.kitten.description || ''
route=this.props.match.params.id
/>
)
【讨论】:
【参考方案2】:当您的 Edit 组件首次加载时,它没有 kitten
。因此出现错误。
您需要做的是创建一个empty
小猫。在您的编辑组件中...
this.state = kitten: name:''
这将在组件的第一次挂载/渲染时将小猫的名称设置为空字符串。
【讨论】:
以上是关于将状态作为道具传递给子组件不起作用的主要内容,如果未能解决你的问题,请参考以下文章
在 setState 不起作用后,Reactjs 将值作为道具传递