2016-10-04 134 views
1

智能/哑组件使用选择说我有一个最顶层的智能组件调用预测,看起来像这样:在终极版

function mapStateToProps(state) { 
    return { 
    dates: state.getIn(['forecast', 'dates']), 
    isFetching: state.getIn(['forecast', 'isFetching']) 
    }; 
} 

export default connect(mapStateToProps, { 
    fetchForecast 
})(Forecast)); 

它包装一个预测成分是这样的:

import { getSummary, getDayForecast } from '../selectors/selectors'; 
export default class Forecast extends Component { 

    render() { 
    const { dates, isFetching } = this.props; 

    return (
     <div className="row"> 
     {dates.map(date => (
      <Weather 
      key={date} 
      date={date} 
      getSummary={getSummary} 
      getDayForecast={getDayForecast} 
      /> 
     ))} 
     </div> 
    ); 
    } 
}; 

这里我将2个选择器作为道具传递给Weather组件。该选择是这样的:

import { createSelector } from 'reselect'; 
import moment from 'moment'; 
import { fromJS } from 'immutable'; 

const getDay = (state, key) => state.getIn(['forecast', 'forecast']).find(x => x.get('id') === key); 

export const getSummary = createSelector(
    [getDay], 
    (day => { 
    const firstPeriod = day.get('periods').first(); 

    return fromJS({ 
     date: day.get('date'), 
     outlook: firstPeriod.get('outlook'), 
     icon: firstPeriod.get('icon') 
    }); 
    }) 
); 

export const getDayForecast = createSelector(
    [getDay], 
    (day) => day.get('periods').map(period => fromJS({id: period.get('id') })) 
); 

我没有通过这些选择下来的道具,我可以很容易地只是参考他们在天气组件,但我很困惑,我怎么会用在这些选择Weather组件作为Weather组件也是愚蠢的,并且不会有任何状态的引用。我只想要一个容器或智能组件在顶层,子组件调用或获取道具传递。

我可以看到使这项工作的唯一方法是有一个intermediatary WeatherContainer组件,它看起来是这样的:

import React, { Component, PropTypes } from 'react'; 
import { connect } from 'react-redux'; 

import Weather from '../components/Weather'; 

import { getSummary, getDayForecast } from '../selectors/selectors'; 

function mapStateToProps(state, ownProps) { 
    return { 
    summary: getSummary(state, ownProps.date), 
    detail: getDayForecast(state, ownProps.date) 
    }; 
} 

export default(connect(mapStateToProps,{}))(Weather); 

,我会叫这样的:

{dates.map(date => (
     <WeatherContainer 
     key={date} 
     date={date} 
     getSummary={getSummary} 
     getDayForecast={getDayForecast} 
     /> 
    ))} 

这似乎必须创建像这样的容器组件是完全错误的。

我怎样才能使哑元件使用选择的或如何传递下来的道具记住霸菱,他们也需要参照状态?

+0

你的选择器返回的是不可变的对象,这是过度杀伤。与普通物体相比,它的性能也更差,也更难使用。把React-Redux上下文中的'props'想象成一个临时变量。这是不变的,但没有必要执行或管理。 – DDS

回答

4

在你WeatherContainermapStateToProps你用你的选择,但你仍然传递下来的道具。这不是必需的。

除此之外,你应该知道,在创建容器WeatherContainer是去了解事情的正确方法。你应该从来没有给组件一个选择器。它们应该始终在mapStateToProps中使用。 React-Redux将在状态更改时重新评估此值,并在结果不同时告诉React更新组件。这是非常重要的一点。如果你只是抢到一个组件内的状态,是否使用选择与否,随即反应过来,终极版不知道你正在使用此数据不会,我们能够告诉反应,重新描绘当此数据变化。

现在很多人都对这件事感到困惑。有愚蠢的组件,只是显示的东西,和容器组件,其中东西,就像进行API调用或实现排序功能。但是当你把一个愚蠢的组件和connect它给Redux,那么这不会成为一个智能或容器组件。它仍然只显示东西。即使您使用mapDispatchToProps来为某些事件侦听器提供它,但这仍然不能使组件变得更加智能。如果它包含mapStateToPropsmapDispatchToProps中的重要代码,我想可能会变得很聪明。但这就是生活。这些事情之间的界限只是模糊。

Redux Way是连接需要数据的所有东西。您一定可以将数据传递给孩子,就像使用普通的React一样,但您可以通过连接组件来创建更高性能的应用程序。不过,这取决于你自己决定。但是任何你从商店获取数据的地方都很重要,它应该放在mapStateToProps之内,这样React-Redux可以关注数据。只要数据来自mapStateToProps,您就可以安全地将其从父母传递给孩子。

这意味着将选择器传递给孩子是一个禁忌。另外,孩子在哪里将状态作为参数传递给选择器?它工作不好,所以这不是一个好主意。请注意,无论何时您使用connect组件,您都不会创建一个全新的组件。只是一个简单的包装。它应该在很少的几行中包含非常少的代码。这不应该让你停下来。只是为了它。 connect这些组件。

我还应该提到,您可以直接在weather.js文件中连接Weather组件。除非您要重复使用它,否则不需要保留未连接的组件。对于测试,您可以使用命名导出export未连接的组件。如果稍后决定需要重新使用Weather组件,则始终可以轻松地将组件和连接呼叫分离为单独的文件。

+0

如果我点击一个父组件进行异步调用以获取并显示该父项的子记录,那么如果我有一个主/子场景会怎么样。选择器对此有用吗? 我只想在第一时间拨打电话,而不是在此后拨打 – dagda1

+0

号码。这是一个禁忌,因为您需要发送操作将该数据放入Redux存储,并让Redux执行任何必要的重新显示操作* for *你,孩子的组成部分或兄弟姐妹或任何地方。这是好处的一部分:现在或未来版本的应用程序中依赖于此数据的任何内容都会得到更新,并有保证。这是Redux的*主要优势*:应用程序的每个部分都同意这些数据。这实际上并不取决于您想要对API或后端或朋友进行多少次调用,也不取决于何时以及如何调用。 – DDS

+0

选择器将用于从商店获取数据。使用选择器的原因是,当商店形状改变时,选择器和选择器可以被修改以返回正确的数据。选择器也可以调用其他(父)选择器,所以如果你移动状态片,你可能只需要改变一个选择器。有时选择器也可以格式化数据,但它们确实是格式化器。不过,[Reselect](https://github.com/reactjs/reselect)或其他通用[memoizers](https://gist.github.com/addyosmani/1225243),对于格式化程序也可以正常工作。 – DDS