Javascript 使用<;通过上下文传递存储;供应商>;在基于connect()的方案中不工作

Javascript 使用<;通过上下文传递存储;供应商>;在基于connect()的方案中不工作,javascript,reactjs,redux,react-redux,Javascript,Reactjs,Redux,React Redux,编辑:总结-我的问题的最初原因实际上是一个打字错误:由于大写字母“G”,它不起作用 然而,善意的回答者不仅解决了打字错误,而且还解决了我所采取的方法中的错误前提——如果您也正在使用提供商和connect通过商店,他们的回答与您相关。我已更新问题的标题以反映这一点 我试图按照中的说明进行操作,但由于使用react redux中的传递了商店,我感到很难过 我有一个根组件: export default class Root extends Component { render() {

编辑:总结-我的问题的最初原因实际上是一个打字错误:由于大写字母“G”,它不起作用

然而,善意的回答者不仅解决了打字错误,而且还解决了我所采取的方法中的错误前提——如果您也正在使用提供商和connect通过商店,他们的回答与您相关。我已更新问题的标题以反映这一点


我试图按照中的说明进行操作,但由于使用react redux中的
传递了商店,我感到很难过

我有一个根组件:

export default class Root extends Component {
   render() {

      const { store } = this.props

      return (
         <Provider store={store}>
            <div>
               <ReduxRouter />
               <DevTools />
            </div>
         </Provider>
      )
   }
}
(不是我的代码,这是一个支持react native和browser client的框架,我正在使用它开始工作)

我错过了什么


我正在从视频中复制此内容-请注意,AddTodo组件没有使用connect()进行“包装”:

const AddTodo=(props,{store})=>{
让输入;
返回(
{
输入=节点;
}} />
{
仓库调度({
键入:“ADD_TODO”,
id:nextTodoId++,
文本:input.value
})
input.value='';
}}>
添加待办事项
);
};
AddTodo.contextTypes={
存储:React.PropTypes.object
};
更新:
store.GetState()
不是一个方法

store.getState()
是一种方法


您对
connect
的使用有点倒退

connect
将函数作为第一个参数,让您可以访问商店和道具。传递给另一侧的是视图组件将作为其
道具接收的对象

const MyWidget = (props) => {
  const { title, data } = props;
  return (<div>{title}{data}</div>);
};
const MyWidgetContainer = connect((store, props) => {
  return { title: props.title, data: store.a.b.widget.data };
})(MyWidget);
MyWidget现在可以单独访问商店

在您的情况下,您没有将所看到的transformer功能赋予
connect
,而是将其应用于
,这意味着如果您在应用程序中使用
HomeContainer
,则
Home
将有权访问商店

这是100%的好,但除非您也包装您的演示组件,否则您的演示组件将没有存储访问权限。这也没关系,但这意味着
Home
现在需要传递组件所需的道具

// Home

Home {
  render () {
    { a, b, c } = this.props;
    return (
      <MyWidget a={ a } b={ b } c={ c } />
    );
  }
}
container = connect(/* ... */)(Home);
//主页
家{
渲染(){
{a,b,c}=this.props;
返回(
);
}
}
容器=连接(/*…*/)(主);
是正确的,但我想澄清几件事

您似乎对表示组件和容器组件以及
connect()
的角色有很多困惑。我建议你再看一次相关的视频,并确保看到最后

  • 实际上,
    store.GetState()
    不是有效的方法
    store.getState()
    is
  • 如果手动使用
    store.getState()
    则必须在某个地方使用
    store.subscribe()
    ,以便始终获得最新状态。您从视频中粘贴的示例
    AddTodo
    组件本身无法工作-它只在视频中工作,因为我们在顶部有一个
    存储。订阅(渲染)
  • 本课程后面的视频将讨论如何从顶部重新渲染会变得麻烦,此时我们将介绍容器组件。随后我们展示了使用
    connect()
    生成容器组件比手工编写更容易。在这种情况下,
    connect()
    负责订阅存储
  • 在您的案例中,仅在
    connect()
    中包装
    Home
    ,没有任何效果
    connect()
    生成订阅存储的容器组件,但如果不指定
    mapstatetops
    参数,它甚至不会订阅存储使用
    connect()
    是手动使用
    store.getState()
    store.subscribe()
    contextTypes
    的有效替代方法。
    在某些东西上使用
    connect()
    和调用
    store.getState()
    或指定
    contextTypes
    ,都是没有意义的
  • 因此,再次总结一下:

    • store.getState()和
      store.subscribe()是低级API。如果你决定使用它们,你必须一起使用它们;一个没有另一个是没有意义的

    • connect()
      负责调用
      getState()
      subscribe()
      并通过道具将必要的信息传递给子组件。如果使用
      connect()
      ,则永远不需要
      store.getState()
      store.subscribe()
      、或
      contextTypes
      connect()
      的全部目的就是将它们抽象出来

    这些课程教给你所有这些工具,告诉你没有魔法。但是,通常不应该在实际应用程序中使用
    store.getState()
    store.subscribe()
    。除非您访问低级API有非常具体的原因,否则您几乎应该只使用
    connect()

    我将大致如下重写您的代码:

    // ProjectSummary is a presentational component
    // that takes projects as a prop and doesn't care
    // where it comes from.
    const ProjectsSummary = ({ projects }) => {
      return (
        <div className="home-projects col-md-10">
          <h3>Projects</h3>
          <ul>
            {projects.map(p => <li key={p.id}>{p.contract.client}</li>)}
          </ul>
        </div>
      )
    }
    
    // Home by itself is also a presentational component
    // that takes projects as a prop. However we will
    // wrap it in a container component below using connect().
    // Note that I got rid of inheritance: it's an anti-pattern
    // in React. Never inherit components; instead, use regular
    // composition and pass data as props when necessary.
    const Home = ({ projects }) => (
      <div className="home-page container-fluid">
        <BasePage />
        <HomeLeftBar />
        <HomePageHeader />
        <ProjectsSummary projects={projects} />
      </div>
    )
    
    // How to calculate props for <Home />
    // based on the current state of the store?
    const mapStateToProps = (state) => ({
      projects: state.projects
    })
    
    // Generate a container component
    // that renders <Home /> with props from store.
    export default connect(
      mapStateToProps
    )(Home)
    
    //ProjectSummary是一个表示组件
    //这将项目视为道具,并不在意
    //它来自哪里。
    常量项目汇总=({projects})=>{
    返回(
    项目
    
      {projects.map(p=>
    • {p.contract.client}
    • )}
    ) } //家本身也是一种表现成分 //这将项目视为支柱。无论如何,我们会 //使用connect()将其包装在下面的容器组件中。 //注意,我去掉了继承:这是一种反模式 //在反应中。永远不要继承组件;相反,使用常规的 //必要时合成并传递数据作为道具。 const Home=({projects})=>( ) //如何计算道具 //基于商店的当前状态? 常量MapStateTops
    const AddTodo = (props, { store }) => {
      let input;
    
      return (
        <div>
          <input ref={node => {
            input = node;
          }} />
          <button onClick={() => {
            store.dispatch({
              type: 'ADD_TODO',
              id: nextTodoId++,
              text: input.value
            })
            input.value = '';
          }}>
            Add Todo
          </button>
        </div>
      );
    };
    AddTodo.contextTypes = {
      store: React.PropTypes.object
    };
    
    const MyWidget = (props) => {
      const { title, data } = props;
      return (<div>{title}{data}</div>);
    };
    const MyWidgetContainer = connect((store, props) => {
      return { title: props.title, data: store.a.b.widget.data };
    })(MyWidget);
    
    import MyWidget from "./components/my-widget/";
    
    //...
    render ( ) {
       return (
         <MyWidget title="My Title" />
       );
    }
    
    // Home
    
    Home {
      render () {
        { a, b, c } = this.props;
        return (
          <MyWidget a={ a } b={ b } c={ c } />
        );
      }
    }
    container = connect(/* ... */)(Home);
    
    // ProjectSummary is a presentational component
    // that takes projects as a prop and doesn't care
    // where it comes from.
    const ProjectsSummary = ({ projects }) => {
      return (
        <div className="home-projects col-md-10">
          <h3>Projects</h3>
          <ul>
            {projects.map(p => <li key={p.id}>{p.contract.client}</li>)}
          </ul>
        </div>
      )
    }
    
    // Home by itself is also a presentational component
    // that takes projects as a prop. However we will
    // wrap it in a container component below using connect().
    // Note that I got rid of inheritance: it's an anti-pattern
    // in React. Never inherit components; instead, use regular
    // composition and pass data as props when necessary.
    const Home = ({ projects }) => (
      <div className="home-page container-fluid">
        <BasePage />
        <HomeLeftBar />
        <HomePageHeader />
        <ProjectsSummary projects={projects} />
      </div>
    )
    
    // How to calculate props for <Home />
    // based on the current state of the store?
    const mapStateToProps = (state) => ({
      projects: state.projects
    })
    
    // Generate a container component
    // that renders <Home /> with props from store.
    export default connect(
      mapStateToProps
    )(Home)