为啥我不能访问上下文的方法或属性

Posted

技术标签:

【中文标题】为啥我不能访问上下文的方法或属性【英文标题】:Why can't I access the context's methods or properties为什么我不能访问上下文的方法或属性 【发布时间】:2019-09-23 11:22:56 【问题描述】:

我正在尝试使用 React 的上下文 api 来管理全局状态。当我尝试调用上下文方法或访问上下文属性时,我收到错误消息“this.context.setUser 函数不存在”或“未定义”。

然而,我已经能够将值硬编码到上下文的状态中并检索硬编码的值。

Feed 上下文

    import React,  Component  from 'react'

    const FeedContext = React.createContext(
      Feed: [],
      user: '',
      error: null,
      setError: () => ,
      clearError: () => ,
      setFeed: () => ,
      setUser: () => 
    )

     export default FeedContext

    export class FeedProvider extends Component 
      state = 
        feed: [],
        error: null,
        user: ''
      ;

      setUser = user => 
        this.setState( user )
      

      setFeed = Feed => 
        this.setState( Feed )
      

      setError = error => 

        console.error()
        this.setState( error )
      

      clearError = () => 
        console.log('context is accessed')
        this.setState( error: null )
      

      render() 
        const value = 
          feed: this.state.feed,
          error: this.state.error,
          setError: this.setError,
          clearError: this.clearError,
          setFeed: this.setFeed,
          setUser: this.setUser
        

        return (
          <FeedContext.Provider value=value>
            this.props.children
          </FeedContext.Provider>
        )
      
    

AccountPanel.js

    import React from 'react';
    import FeedContext from "../../contexts/FeedContext";

    // functional component
    class AccountPanel extends React.Component 


    static contextType = FeedContext


    renderUserInfo()
        const  user = []  = this.context;

        //this returns "undefined"
        console.log(user.user)

        //this returns "user.setUser() is not a function"
        user.setUser('newUser')

        //this returns ' '
        this.context.setUser('y')
        console.log(user)
    

    render()
        return (
            <section>
                 this.renderUserInfo() 
               AccountPanel
            </section>
        )
       

    

    export default AccountPanel;

我希望能够通过 this.context.setUser('newUser) 更新上下文状态/用户,然后在我的导航栏组件中使用该值

【问题讨论】:

我最好的猜测是 AccountPanelnot 由上下文提供程序包装的。你能分享一下呈现AccountPanel和提供者的代码吗? 另一个猜测是静态属性没有正确编译。你能检查一下你的.babelrc 插件中有@babel/plugin-proposal-class-properties 吗? @Matthieu Account panel.js(第二个 sn-pt)并且提供者是从 sn-pt 底部的 FeedContext 中返回的。这段代码实际上来自我正在学习的一门课程,我正在尝试实现他们使用的模式。但这不是我通常看到的实现方式。 我的意思是你的应用程序的某些部分应该import FeedProvider 并使用它。 AccountPanel 应位于应用层次结构中的 FeedProvider 之下。 当我们这样做时:上下文提供者的值似乎缺少user: this.state.user, 【参考方案1】:

文件 App.js

import React,  Component  from 'react';
import AccountPanel from "./components/AccountPanel";
import  FeedProvider  from './components/FeedContext';


class App extends Component 

  render() 
    return (
      <div className="App">
      <FeedProvider>
          <AccountPanel />
      </FeedProvider>
      </div>
    );
  


export default App;

文件:FeedContext.js

import React,  Component  from 'react'

const FeedContext = React.createContext(
  Feed: [],
  user: '',
  error: null,
  setError: () => ,
  clearError: () => ,
  setFeed: () => ,
  setUser: () => 
)

export default FeedContext

export class FeedProvider extends Component 

  constructor(props)
    super(props);
    this.state = 
      feed: [],
      error: null,
      user: "11"
    ;
  


  setUser = user => 
    console.log(`setting usr fns called for username: $user`);
    this.setState( user );
  

  setFeed = Feed => 
    this.setState( Feed )
  

  setError = error => 

    console.error()
    this.setState( error )
  

  clearError = () => 
    console.log('context is accessed')
    this.setState( error: null )
  

  componentDidMount()
    console.log('FeedProvider:componentDidMount');
  

  render() 
    let value1 = 

      Feed:this.state.feed,
      user:this.state.user,
      error:this.state.error,
      setError:this.setError,
      clearError:this.clearError,
      setFeed:this.setFeed,
      setUser:this.setUser
    

    return (
      <FeedContext.Provider value=value1>
        this.props.children
      </FeedContext.Provider>
    )
  

文件:AccountPanel.js

import React from 'react';
import FeedContext from "./FeedContext";

    // functional component
    class AccountPanel extends React.Component 


    static contextType = FeedContext
    // return BlogPost component html/(JSX)

    componentDidMount()
        console.log('AccountPanel:componentDidMount');
        console.log(this.context);
        const  value  = this.context;

        //this returns "undefined"
        console.log(value.user)

        //this returns "user.setUser() is not a function"
        console.log(value.setUser);
        value.setUser('newUser');
    


    render()
        const  value  = this.context;
        console.log(`Value of new User is : $value.user`);
        return (
            <section>
               AccountPanel
            </section>
        )
       

    

    export default AccountPanel;

希望这会有所帮助:)

【讨论】:

感谢您的帮助,但我已经能够从上下文中检索硬编码数据...我需要能够使用 context.setUser() 来更新用户属性,然后重新获取它...这可以在没有从父母那里传递道具的情况下实现... 我知道数据是硬编码的,但是一旦调用了 set 用户,它就会被覆盖。 你为什么不至少提供一个错误的解释而不是发布整个解决方案。

以上是关于为啥我不能访问上下文的方法或属性的主要内容,如果未能解决你的问题,请参考以下文章

为啥我在引入属性类型提示时突然收到“在初始化之前不能访问类型属性”错误?

为啥我不能在对象数组的 for-in 循环中访问对象属性? [复制]

为啥 dir(x) 中的所有名称都不能用于属性访问?

为啥我不能访问猫鼬模式的方法?

为啥类或接口不能接收私有或受保护的访问修饰符?

为啥 var_dump 可以确定私有变量的值,但在尝试访问单个属性时却不能