javascript - 我无法理解为什么具有 'connect()' 的组件在 react 中是有状态的

标签 javascript reactjs redux react-redux

我的问题和标题一样。

假设我编写了以下代码。

class TODOList extends Component {  
  render() {
    const {todos, onClick} = this.props;
    return (
      <ul>
            {todos.map(todo =>
                <Todo 
                    key={todo.id}
                    onClick={onClick}
                    {...todo}
                />
             )}
      </ul>
    );
  }
}


const mapStateToProps = (state) => {  
  return {
    todos: state.todos
  }
}


const mapDispatchToProps = (dispatch) => {  
    return {
        onClick(data){
          dispatch(complete(data)) 
        }
    }
}


export default connect(mapStateToProps,mapDispatchToProps)(TODOList); 

现在,在最后一行之后,此代码将导出带有状态的 TODOList 组件作为 Prop 。这并不是说它包含状态,而是只是接收到状态并将它们作为“ Prop ”,就像方法名称“mapStateToProps”所解释的那样。

在 Dan Abramov 撰写的中篇文章 ( https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0 ) 中,容器组件将数据作为状态处理,而展示属性作为 Prop 处理。它不是一个将数据作为 Prop 处理的展示组件吗?我坚持认为正确的容器应该是下面这样的容器。

class CommentList extends React.Component {
  this.state = { comments: [] };

  componentDidMount() {
    fetchSomeComments(comments =>
      this.setState({ comments: comments }));
  }
  render() {
    return (
      <ul>
        {this.state.comments.map(c => (
          <li>{c.body}—{c.author}</li>
        ))}
      </ul>
    );
  }
}

当我尝试制作“有状态”(不按属性处理数据)容器组件时,我不确定为什么 react-redux 将 API 命名为“mapStateToProps”

最佳答案

首先这些指南不是圣经的一部分
您应该编写易于您和您的团队推理的代码。

我认为您遗漏了一些东西,redux 容器与 react 容器不同。
我的意思是,connect 将为您创建容器,这并不意味着包装的组件一个容器。

基本上,您可以从同一个文件导出两个版本,容器(连接版本)和演示版本(非连接版本)。

另一件通常让人们失望的事情是 mapStateToProps 的函数和参数的名称。
我更喜欢 mapStoreToProps 中的名称

map the redux store to the component's props.

当我们处于 react 的上下文中时,名称 state 可能会造成混淆。

编辑
作为您评论的跟进:

I totally didn't know these two are actually different. Could you please tell me about more details

它们的不同之处在于 connect 为您创建“容器”的方式。

connect 是创建 Container Component 的高阶组件为我们提供所有订阅逻辑 + 函数,将商店和 Action 创建者的部分作为 Prop (mapStateToPropsmapDispatchToProps)传递给它的 child 。

“普通”容器通常是指您手工编写的组件,它通常不处理事物的外观,而是处理应用程序的某些逻辑。

至于其他评论如

The connect HoC of react-redux just injects the properties you can request into your component. It returns a new component that is wrapped around your component so that it can update your component whenever the state you're interested in the redux store is modified

正如我上面提到的,这是部分正确的。它不仅仅是将属性注入(inject)我们的组件,它还订阅了商店,从 Provider 中获取它(通过 context),它在做所有这些时都考虑到了优化,所以我们不必自己做。

I'm not sure how mapStateToProps can confuse someone. We are talking about a state management library

我看到一些开发者误解了这一点,因为 react 有一个 stateredux 有一个 store (至少在大多数教程和文档中都是这样调用它的)。
这可能会让一些刚接触 reactredux 的人感到困惑。

编辑2

It was a bit confusing due to the sentence 'it doesn't mean the wraped component is a Container.' Why is the wrapped component not a container? Isn't a component created by connect also a container?

我的意思是您编写的包装组件不一定是容器。
您可以连接一个“Presentation”组件:

const Link = ({ active, children, onClick }) => {
  if (active) {
    return <span>{children}</span>
  }

  return (
    <a
      href=""
      onClick={e => {
        e.preventDefault()
        onClick()
      }}
    >
      {children}
    </a>
  )
}

// ...
export default connect(mapState, mapDispatch)(Link)

关于javascript - 我无法理解为什么具有 'connect()' 的组件在 react 中是有状态的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53802181/

相关文章:

javascript - 允许用户第二次尝试获得正确答案

javascript - 如何让这个 React 方法返回语句/变量?

javascript - 是否可以将内部 Div Click 绑定(bind)到外部 Div?

javascript - 为什么当我调用代理服务器 api 时会附加网站 url

javascript - 将参数传递给无状态功能组件中的事件函数

javascript - Angularjs:ng模型无法访问

javascript - Ext.create 返回构造函数而不是对象

javascript - 加载后的 iframe javascript

reactjs - React JS 多个提交按钮 react-hook-form

javascript - React Native,Redux 找不到上下文