将状态作为道具传递给子组件不起作用
Passing state into child component as props not working
我正在尝试使用 React 和 React Router 构建一个示例 CRUD 应用程序,但我不明白为什么状态没有按照我期望的方式传递到子组件中。当我点击 edit
路由时,它会呈现 Edit
组件,该组件从数据库中获取我想要的小猫并将其信息发送到 Form 组件,该组件可用于编辑现有的小猫或添加新的一个。
这是编辑组件:
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
避免尝试将该信息作为 props 发送到 Form
组件。
我做错了什么?
当您的编辑组件第一次加载时,它没有 kitten
。因此错误。
您需要做的是创建一只 empty
小猫。在您的编辑组件中...
this.state = { kitten: {name:''} }
这会在组件的第一个 mount/render 上将小猫的名字设置为空字符串。
两件事,
首先:在您的编辑组件中,您没有初始化小猫状态,而是根据 API 结果设置它。但是,componentDidMount 在组件被调用后被调用,因此 DOM 被渲染了一次,并且第一次它没有找到 this.state.kitten.name
或 this.state.kitten.description
的任何值。
只有在API成功后才能设置小猫状态。因此,只需在渲染时进行检查。
其次:在 setState
函数之后有 console.log(this.state.kitten.name)
。然而setState is asynchronous
。看到这个问题:
因此您需要在 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}
/>
)
}
}
我正在尝试使用 React 和 React Router 构建一个示例 CRUD 应用程序,但我不明白为什么状态没有按照我期望的方式传递到子组件中。当我点击 edit
路由时,它会呈现 Edit
组件,该组件从数据库中获取我想要的小猫并将其信息发送到 Form 组件,该组件可用于编辑现有的小猫或添加新的一个。
这是编辑组件:
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
避免尝试将该信息作为 props 发送到 Form
组件。
我做错了什么?
当您的编辑组件第一次加载时,它没有 kitten
。因此错误。
您需要做的是创建一只 empty
小猫。在您的编辑组件中...
this.state = { kitten: {name:''} }
这会在组件的第一个 mount/render 上将小猫的名字设置为空字符串。
两件事,
首先:在您的编辑组件中,您没有初始化小猫状态,而是根据 API 结果设置它。但是,componentDidMount 在组件被调用后被调用,因此 DOM 被渲染了一次,并且第一次它没有找到 this.state.kitten.name
或 this.state.kitten.description
的任何值。
只有在API成功后才能设置小猫状态。因此,只需在渲染时进行检查。
其次:在 setState
函数之后有 console.log(this.state.kitten.name)
。然而setState is asynchronous
。看到这个问题:
因此您需要在 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}
/>
)
}
}