将状态作为道具传递给子组件不起作用

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.namethis.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 将值作为道具传递

Vuejs将道具从父组件传递到子组件不起作用

Vue JS rc-1 通过道具传递数据不起作用

Storybook 6 装饰器将道具传递给故事不起作用

如何使用 Vue.js 路由器将状态和事件处理程序作为道具传递给子组件?

当用户输入通过来自另一个组件的道具的文本时,在反应 js 中不起作用