反应无状态子组件不会更新父组件中的状态更改

Posted

技术标签:

【中文标题】反应无状态子组件不会更新父组件中的状态更改【英文标题】:react stateless child components do not update on state change in parent component 【发布时间】:2018-11-03 03:57:33 【问题描述】:

我正在构建一个小型选项卡式应用程序,其中每个选项卡呈现一个子组件。

我希望每个选项卡显示不同的内容,因此我在 render() .... 之外创建了一个对象 contentTypes 以将每个选项卡映射到其对应的子组件。子组件通过 props 接收处理程序和状态。

class App extends Component 
    state =
        contentType: "A",
        title: "Overview",
        searchContent: ""
    

    tabHandler= (content,event)=>
       console.log("clicked");
       this.setState(
          title: event.target.name,
          contentType: content
       );
    
    searchHandler = (event) => 

       // this performs a search on a database and 
       //returns suggestions for the current input

       this.setState(
          searchContent: event.target.value
       );
     

    contentTypes = 
        A: <A/>,
        B: <B/>,
        C: <C onchange=this.searchHandler.bind(this) content=this.state.searchContent/>
    ;
    render() 
      return (
        <div className="row">
          <ul>
           <Tab click=this.tabHandler.bind(this) id="A" name="A"/>
           <Tab click=this.tabHandler.bind(this) id="B" name="B"/>
           <Tab click=this.tabHandler.bind(this) id="C" name="C"/>
         </ul>
        <h1 id="title">this.state.title</h1>

        this.contentTypes[this.state.contentType]

       </div>
     );
   

子组件是无状态的,有点像这样定义:

import React from 'react'
import Field from './form-builder/field';

const C = (props) => 

return(

    // Field is another stateless component with formatted <input> tags

    <Field type="text" name="search" content=props.content onchange=props.onchange/>
  );
 

export default C;

字段定义如下:

import React from 'react';

const field = (props) => 
    <li className="field">
       <input type="text" onChange=props.onchange value=props.content />
       <label htmlFor=props.name>props.value</label>
    </li>

export default field;

问题是当我从Field 内部调用处理程序来更新父组件中的状态时(带有render() .... 的那个)子组件不会更新为新状态。

关于如何解决这个问题的任何想法?

【问题讨论】:

请同时添加Field @RIYAJKHAN 添加了 【参考方案1】:

您将contentTypes 定义为类属性。 它实际上是一样的:

class App extends Component 
  constructor() 
    this.contentTypes = 
      A: <A />,
      B: <B />,
      C: <C
           onchange=this.searchHandler.bind(this)
           content=this.state.searchContent/>
    
  

所以在构造函数中渲染的元素永远不会得到任何道具的更新。 这是解决此问题的方法:

class App extends Component 
  contentTypes = 
    A: () => (<A/>),
    B: () => (<B/>),
    C: () => (
        <C
          onchange=this.searchHandler.bind(this)
          content=this.state.searchContent />
       )
  

  // ...

  render () 
    const Content = this.contentTypes[this.state.contentType]

    return (
      <div>
      /* ... */
        <Content />
      </div>
    )
  

【讨论】:

以上是关于反应无状态子组件不会更新父组件中的状态更改的主要内容,如果未能解决你的问题,请参考以下文章

当提供者组件父状态发生变化时,为啥不能更新子组件中的值(带有反应上下文)?

通过反应上下文 api 将子状态传递给父组件

如何在反应中将最新状态从子组件传递给父组件

React js从父事件中更新子状态

使用 Lodash.remove 通过 Vuex 突变更改状态不会触发我的 Vue 组件中的反应式重新渲染

React 子组件在父组件中更新状态后如何将其重置回原始状态