是否反对redux哲学将redux状态复制到本地状态?

时间:2017-02-28 00:45:14

标签: reactjs redux

import React, { Component } from 'react'
import _ from 'lodash'
import { PageHeader, Row, Col, FormGroup, ControlLabel, Button, FormControl, Panel } from 'react-bootstrap'

import FieldGroup from '../fieldGroup/fieldGroup'
import PassagePreview from './preview'

class PassageDetail extends Component {
  constructor(props) {
    super(props)

    this.handleChange = this.handleChange.bind(this)

    this.state = {
      passageDetails: {}
    }

  }

  componentDidMount() {
    this.props.fetchPassage(this.props.params.passageId)
  }

  componentWillReceiveProps(nextProps) {
    if(nextProps.passageState.passageStatus === 'success') {
      this.setState({passageDetails: nextProps.passageState.passage})
    }
  }

  handleChange(e) {
    let passageDetails = this.state.passageDetails

    passageDetails[e.target.name] = e.target.value

    this.setState({passageDetails})
  }

  render() {
    if(this.props.passageState.passageStatus !== 'success') {
      return null
    }
    return (
      <div>
        <PageHeader>
          Create Passage
        </PageHeader>
        <Row>
          <Col md={6}>
            <FieldGroup
              type="text"
              label="Passage Title"
              name="title"
              onChange={this.handleChange}
              value={this.state.passageDetails.title}
            />

            <FieldGroup
              type="text"
              label="Passage Author"
            />
            <FormGroup>
              <ControlLabel>Passage Text</ControlLabel>
              <FormControl componentClass="textarea" placeholder="textarea" rows="20" />
            </FormGroup>
          </Col>
          <Col md={6}>
            <PassagePreview passageDetails={this.state.passageDetails} />
          </Col>
        </Row>

        <Row>
          <Col md={6} mdOffset={6}>
            <Button block bsStyle="primary">Create Passage</Button>
          </Col>
        </Row>
      </div>
    )
  }
}

export default PassageDetail

那是我的组成部分。容器是:

import { connect } from 'react-redux'
import * as PassagesActions from '../actions/passages'
import PassageMain from '../components/passage/main'

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

const mapDispatchToProps = (dispatch) => {
  return {
    fetchPassages: () => {
      const params = {
        url: `${process.env.REACT_APP_API_ENDPOINT}/passages`
      }
      dispatch(PassagesActions.fetchData(params, 'passages'))
    },
    fetchPassage: (passageId) => {
      const params = {
        url: `${process.env.REACT_APP_API_ENDPOINT}/passages/${passageId}`
      }
      dispatch(PassagesActions.fetchData(params, 'passage'))
    }
  }
}

export default connect(
  mapStateToProps, mapDispatchToProps
)(PassageMain)

所以你可以在我的componentDidMount中看到我正在进行API调用(通过redux),在componentWillReceiveProps中,我正在将其复制到我的本地状态。我的想法是,如果我对passage进行更改,则在组件级别完成,然后我可以通过一些尚未创建的redux操作将该对象传回。

这在redux哲学中是否可以接受?我仍然围绕着还原,我很抱歉,如果这个问题毫无意义。

3 个答案:

答案 0 :(得分:3)

其他评论提出了一些好处,但也夸大了案件。根据{{​​3}}处的Redux常见问题解答:

  

使用本地组件状态很好。作为开发人员,您的工作是确定应用程序的状态,以及每个州应该居住的位置。找到适合您的天平,并随身携带。

     

确定应将哪种数据放入Redux的一些常用经验法则:

     
      
  • 应用程序的其他部分是否关心此数据?
  •   
  • 您是否需要能够根据此原始数据创建更多衍生数据?
  •   
  • 是否使用相同的数据来驱动多个组件?
  •   
  • 能否将此状态恢复到给定的时间点(即时间旅行调试)是否对您有价值?
  •   
  • 您是否要缓存数据(例如,如果已经存在,请使用状态,而不是重新请求数据)?
  •   

所以,如果你想使用本地组件状态作为&#34;临时数据&#34;在使用结果发送操作之前的区域,没关系。

答案 1 :(得分:2)

出于好的原因,它违背了“redux哲学”,你有一个架构和框架,用于存储和集中你的应用程序的状态,你应该使用它!如果您使用组件状态,那么您将分散应用程序状态,迟早会发生灾难。尽可能坚持使用Redux架构,仅将组件状态用于较小的UI细节,甚至更好,不要使用它。

看看你的reducer会有所帮助,但是如果你已经在你的Redux商店中持有passages的集合,很明显你不需要组件状态。

如果您已经拥有关于passage的基本信息,并且您需要从服务器为该组件加载更多信息,那么您的所有段落都应该有一个标记,表明您是否已经拥有该信息,因此当您的组件加载只在需要时检索信息。

无需使用componentWillReceiveProps,只需触发操作,在操作完成时更新reducer中的商店即可。你的收藏将有通道,你需要将它传递给组件(所有这些,而不仅仅是id)。

Redux是一个非常低级别的框架,它为您提供了很多自由。如果您怀疑自己是否做出了正确的决定,请始终牢记:

  • 与应用程序相关的任何信息都会进入Redux商店
  • 以任何方式影响应用程序的任何事情都是一个动作
  • React组件使用从用户收集的信息显示信息和fire redux操作,别的

需要注意的另一件事是,您的组件应该只接收所需的属性。你将它传递给整个reducer,这可能完全没问题,但是如果你在reducer中有很多数据不会影响组件,那么性能会降低,因为你会强制React更新组件没有必要这样做。

答案 2 :(得分:1)

更多&#34; Redux&#34;这样做的方法是将一个动作调度到商店以更新状态,让redux重新渲染你的组件。你在这里所拥有的不会被视为良好做法。

问题是组件状态将与商店不同步,因此如果商店更新并触发重新呈现,组件可能会收到新的道具(如果没有其他任何东西正在更新{ {1}})并将覆盖本地状态。

查看Unidirectional Data Flow上的redux文档以及他们add new todos的待办事项示例。