React Context - setState 与消费者内部的 onClick

Posted

技术标签:

【中文标题】React Context - setState 与消费者内部的 onClick【英文标题】:React Context - setState with onClick inside Consumer 【发布时间】:2019-08-11 11:45:05 【问题描述】:

我已经实现了 React Context API,我正在尝试通过子组件中的 onClick 函数更新 Provider 中定义的状态。

这是我到目前为止所做的,在 App.js 我有:

import  createContext  from 'react';
const MyContext = React.createContext();
export class MyProvider extends Component 
    state = 
        currPrj: ''
    

    handleBtnClick = prjCode => 

        this.setState(
            currPrj: prjCode
        )

    

    render() 
        return(
            <MyContext.Provider value=
                state: this.state
            >
                this.props.children
            </MyContext.Provider>
        )
    


export const MyComsumer = MyContext.Consumer;

在我的子组件中,我有:

import React,  Component  from "react";
import  BrowserRouter as Router, Route, Link  from "react-router-dom";
import  MyComsumer  from "../../index";

export class ProjectCard extends Component 

  constructor(props) 
    super(props);

    this.state = 
      // currPrj: ''
    ;
  

  render() 
    return (
      <MyComsumer>
        (context) => (
          <div className="card card-project">
          <p>context.state.currPrj</p>
            <div className="content">
              <div className="author">
                <Link to= `projects/$this.props.code/detail/info`  onClick=() => handleBtnClick(this.props.code) >
                  <h4 className="title">
                    this.props.title
                  </h4>
                </Link>
              </div>
          </div>
        )
      </MyComsumer>
    );
  


export default ProjectCard;

这样我得到以下错误

Failed to compile
./src/components/ProjectCard/ProjectCard.jsx
  Line 32:  'handleBtnClick' is not defined  no-undef

Search for the keywords to learn more about each error.

我不明白为什么,因为:

<p>context.state.currPrj</p>

没有错误...

另外,this.props.code 是否正确传递给函数?

非常感谢。

【问题讨论】:

【参考方案1】:

你可以按照这个:

我的小提琴:https://jsfiddle.net/leolima/ds0o91xa/1/

class Parent extends React.Component 
    	
     	sayHey(son) 
      	alert('Hi father, this is son '+son+' speaking');
      
    	
      render() 
      	const children = React.Children.map(this.props.children, (child, index) => 
          return React.cloneElement(child, 
            someFunction: () => this.sayHey(index)
          );
        );
      
        return (<div>
          <b>Parent</b>
          <hr />
          children
        </div>);
      
    
    
    class Child extends React.Component 
      render() 
        return <div>
          <button onClick=() => this.props.someFunction()>Child</button>
        </div>;
      
    
    
    ReactDOM.render(
    	<Parent>
    	  <Child />
    	  <Child />
    	</Parent>,
      document.getElementById('container')
    );
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="container">
</div>

【讨论】:

【参考方案2】:

由于未定义handleBtnClick,因此存在 linter 错误。它是另一个类的方法,而不是独立函数。

它在上下文消费者函数的范围内不可用。如果消费者应该更新上下文,更新函数应该是上下文的一部分:

<MyContext.Provider value=
    state: this.state,
    update: this.handleBtnClick
>

并像这样使用:

context.update(this.props.code)

【讨论】:

非常感谢,它的工作就像一个魅力!我以为这是一个范围错误,但我不知道如何修复它...... 是否需要将值声明为变量才能avoid unintentional renders? @IanDunn 可能是这样。在通过 props 影响重新渲染的性能敏感的地方,坚持常规优化。对于 hooks API,这些将是非标量常量的常量值和组件范围内的变量的 useMemo。

以上是关于React Context - setState 与消费者内部的 onClick的主要内容,如果未能解决你的问题,请参考以下文章

ReactReact全家桶 -setState-路由组件懒加载-Fragment-Context-组件优化-render props-错误边界-消息订阅发布机制-组件通信方式总结

ReactReact全家桶 -setState-路由组件懒加载-Fragment-Context-组件优化-render props-错误边界-消息订阅发布机制-组件通信方式总结

ReactReact全家桶 -setState-路由组件懒加载-Fragment-Context-组件优化-render props-错误边界-消息订阅发布机制-组件通信方式总结

如何将 React Context 与 Hooks 一起使用?

react组件通信与生命周期

react组件通信与生命周期