2017-02-28 83 views
4
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 

这是我的组件。该容器是:它是否反对redux哲学将复制状态复制到本地状态?

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调用(通过终极版)和componentWillReceiveProps,我认为复制到我的本地状态。这个想法是,如果我对我的passage进行更改,它是在组件级完成的,那么我可以通过一些尚未创建的redux操作将该对象传回。

这是可接受的在REDX哲学?我仍然围绕着REDX,所以我很抱歉如果这个问题没有意义。

回答

3

其他评论提供了一些好的观点,但也夸大了案例。每在http://redux.js.org/docs/faq/OrganizingState.html#organizing-state-only-redux-state的终极版FAQ问题:

使用本地组件的状态是好的。作为一名开发人员,您的工作是确定组成您的应用程序的状态以及每个州应该在哪里生活。找到适合你的平衡点,并与之配合。

拇指的一些常见规则determing什么样的数据应该放在终极版:

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

所以,如果你想用结果分派行动之前,使用本地组件的状态为“临时数据”区域,那也没关系。

1

这样做的更多“Redux”方法是将动作分派到商店以更新状态并让REDX重新呈现您的组件。你在这里有什么不会被认为是好的做法。

问题在于组件状态将与商店不同步,所以如果商店得到更新并且重新呈现被触发,那么组件可能会收到新的道具(可能不会更新state.PassageReducer)并将覆盖本地状态。

看看Unidirectional Data Flow上的redux文档以及他们add new todos的todo示例。

2

由于很好的理由,它违背了“原则”,你有一个架构和一个用于存储和集中你的应用程序状态的框架,你应该使用它!如果您使用组件状态,那么您将分散应用程序状态,迟早会发生灾难。尽可能地坚持Redux体系结构,只对小UI细节使用组件状态,或者甚至更好,根本不使用它。

它可以帮助看看你的减速器,但很明显,如果你已经在你的Redux存储器中持有passages的集合,那么你不需要组件状态。

如果您已经有关于passage的基本信息,并且您需要从该组件的服务器加载更多内容,则所有段落都应该有一个标志,表示您是否已经拥有该信息,因此当您的组件加载时,仅在需要时才提供信息。

没有必要使用componentWillReceiveProps,只需触发操作,当操作完成时更新reducer中的存储,就是这样。你的收藏将会有通道,你需要将它传递给组件(全部,不仅仅是id)。

Redux是一个非常低层的框架,它给你很大的自由。如果你怀疑你是否做了一个正确的决定,始终牢记:

  • 与应用相关的任何信息进入终极版店
  • 任何影响以任何方式的应用程序是一个动作
  • 反应的组分显示与他们收集来自用户的信息,闲来无事

另一个要注意的是,您的组件应该仅仅接收道具信息和火灾终极版动作erties它需要。您将整个reducer传递给它,这可能是完全正确的,但是如果reducer中有很多数据根本不会影响组件,那么性能会降低,因为您会强制React在更新组件时没有必要这样做。