【问题标题】:Which way should I use for Connector in Redux?我应该在 Redux 中为 Connector 使用哪种方式?
【发布时间】:2016-12-14 14:47:15
【问题描述】:

我看到了两种做同样事情的方法,但我不确定哪种方法是正确的。

组件

import React, {Component} from 'react';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import {selectUser} from '../actions/index'


class UserList extends Component {

    renderList() {
        return this.props.users.map((user) => {
            return (
                <li
                    key={user.id}
                    onClick={() => this.props.selectUser(user)}
                >
                    {user.first} {user.last}
                </li>
            );
        });
    }

    render() {
        return (
            <ul>
                {this.renderList()}
            </ul>
        );
    }

}

// Get apps state and pass it as props to UserList
//      > whenever state changes, the UserList will automatically re-render
function mapStateToProps(state) {
    return {
        users: state.users
    };
}

// Get actions and pass them as props to to UserList
//      > now UserList has this.props.selectUser
function matchDispatchToProps(dispatch){
    return bindActionCreators({selectUser: selectUser}, dispatch);
}

// We don't want to return the plain UserList (component) anymore, we want to return the smart Container
//      > UserList is now aware of state and actions
export default connect(mapStateToProps, matchDispatchToProps)(UserList);

https://github.com/buckyroberts/React-Redux-Boilerplate

或者

import React from "react"
import { connect } from "react-redux"

import { fetchUser } from "../actions/userActions"
import { fetchTweets } from "../actions/tweetsActions"

@connect((store) => {
  return {
    user: store.user.user,
    userFetched: store.user.fetched,
    tweets: store.tweets.tweets,
  };
})
export default class Layout extends React.Component {
  componentWillMount() {
    this.props.dispatch(fetchUser())
  }

  fetchTweets() {
    this.props.dispatch(fetchTweets())
  }

  render() {
    const { user, tweets } = this.props;

    if (!tweets.length) {
      return <button onClick={this.fetchTweets.bind(this)}>load tweets</button>
    }

    const mappedTweets = tweets.map(tweet => <li>{tweet.text}</li>)

    return <div>
      <h1>{user.name}</h1>
      <ul>{mappedTweets}</ul>
    </div>
  }
}

https://github.com/learncodeacademy/react-js-tutorials/tree/master/5-redux-react

第一种方式使用mapStateToProps()matchDispatchToProps()两种不同的功能,而另一种方式使用@connect(....).

当我使用@connect 时,我收到一大堆警告,说它尚未最终确定并且可能会更改。

【问题讨论】:

    标签: reactjs redux


    【解决方案1】:

    @ 符号是一个仍然被认为是实验性的装饰器。所以我会使用它,风险自负。如官方文档中所述,您的第一个代码块是更安全的方法。这两个块基本上做同样的事情,但装饰器比任何东西都更糖。

    参考资料:

    【讨论】:

      【解决方案2】:

      我认为第一种方法最终会给你带来更少的问题。其他人也可以插话。

      【讨论】:

      • 这不是一个真正的答案 - 你能添加一些关于什么使第一种方法更好的细节吗?对文档或一些性能测试的任何引用...?
      【解决方案3】:

      Jackson 的回答在各个方面都是正确的,但是他忽略了使用第一个版本进行单元测试的重要性。如果您希望能够对组件进行单元测试(这通常意味着使用未连接的版本进行测试),您需要能够导出已连接和未连接的组件。

      使用您的示例并假设您使用的是 jest/enzyme,您可以执行以下操作:

      // notice importing the disconnected component
      import { UserList } from '../relative/file/path/UserList'
      import { mount } from 'enzyme'
      
      describe('UserList', () => {
        it('displays the Username', () => {
          const users = [{fist: 'Person', last: 'Thing'}, ... ]
          const UserList = mount(<UserList users={users} />)
      
          export(UserList.find('li')[0].text()).toEqual('Person Thing')
        });
      });
      

      一旦您构建了更大的项目,能够进行单元测试将为您的编码生活提供理智。希望这会有所帮助

      【讨论】:

        猜你喜欢
        • 2020-08-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-07
        • 2023-03-27
        • 2010-12-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多