【问题标题】:Alternative of state in stateless component无状态组件中的状态替代
【发布时间】:2017-06-08 02:32:39
【问题描述】:

enter code here我试图将Wheel Picker 组件包含到我的项目中。在有状态组件中覆盖它时效果很好。所以我尝试将其转换为无状态组件,当我滚动滚轮时,所选索引始终索引为默认值(例如:当我滚动到项目编号 10 时,滚轮自动滚动回到默认值 0) 虽然我收到了正确的值。我的组件有问题吗?

import React, {PropTypes} from 'react'

import {   
    Component,
    StyleSheet,
    Text,
    View
} from 'react-native';

import Picker from 'react-native-wheel-picker'
var PickerItem = Picker.Item;
const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: 'transparent',
    },

});

const WheelTimePicker = ({selectedItems, receiveTime}) => {
    const _renderPikcer = () => {
       firstData = {
            secondList: [],
            minuteList: [],
        };
    for (var i = 0; i < 60; i++) {
            firstData.secondList.push(i + 'sec');
            firstData.minuteList.push(i + 'min');
        }

        return (
            <View> 
             <Picker style={{ left: -70, width: 60, height: 60 }}
                selectedValue={selectedItems.selectedMin}
                itemStyle={{ color: "white", fontSize: 20 }}
                onValueChange={(index) => { selectedItems.selectedMin = index;receiveTime(selectedItems); }}>
                {firstData.minuteList.map((value, i) => (
                    <PickerItem label={value} value={i} key={"money" + value} />
                ))}
            </Picker>
            <Picker style={{ left: 60, width: 60, height: 70 }}
                selectedValue={selectedItems.selectedSec}
                itemStyle={{ color: "white", fontSize: 20 }}
                onValueChange={(index) => { selectedItems.selectedSec = index; receiveTime(selectedItems) }}>
                {firstData.secondList.map((value, i) => (
                    <PickerItem label={value} value={i} key={"money" + value} />
                ))}
            </Picker>
            </View>
        );
   }

    return (

        <View style={styles.container}>
  {_renderPikcer()}

        </View>
    );

};

WheelTimePicker.propTypes = { 
     selectedItems: PropTypes.object.isRequired,
  receiveTime: PropTypes.func.isRequired,
};
export default WheelTimePicker;

我把组件是这样的:

 <WheelTimePicker selectedItems={{selectedMin: 2, selectedSec: 0}} receiveTime={(rc)=> _displayTime(rc)}/>

【问题讨论】:

  • 您应该考虑将 redux 集成到您的应用程序中,以便组件通过 props 而不是状态显示值。
  • 我们可以使用无状态组件和Redux来替换所有有状态组件吗?在某些情况下我觉得编写动作和使用全局状态(存储)比使用有状态组件更复杂。
  • 视情况而定 - 如果一个组件不需要与其他组件共享数据,那么将其添加到全局存储中是没有意义的。

标签: reactjs react-native


【解决方案1】:

这是因为您试图修改从父元素传下来的props。 IE。在无状态组件中,传入的参数是 props。道具是只读的 (https://facebook.github.io/react/docs/components-and-props.html#props-are-read-only)

您还尝试更新渲染函数内部的值,这些值可能存在于组件的状态中。在这种特殊情况下,您尝试修改 selectedItems 的内容,这是一个传递给您的组件的道具。

为了更新selectedItems的内容,最好将selectedItems保持为父组件中的状态并使用setState更新值(这可能是您最初的方法,因为您提到“它在有状态组件中覆盖它时效果很好")

例如

class ParentComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      selectedItems: {
        selectedMin: 2,
        selectedSec: 0
      }
    }
  }

  _updateSelectedItems(rc) {
    this.setState({
      selectedItems: {
        selectedMin: rc.selectedMin || this.state.selectedMin,
        selectedSec: rc.selectedSec || this.state.selectedSec
      }
    })
  }

  render() {
    return (
      <WheelTimePicker selectedItems={this.state.selectedItems} receiveTime={(rc) => this._updateSelectedItems(rc)}/>
    )
  }
}

这样,您的WheelTimePicker 组件可以是无状态的。在您的Picker 中,可能需要稍微调整一下:

<Picker
  ...
  onValueChange={(index) => { receiveTime({selectedMin:index});}}
/>

【讨论】:

  • 你是对的。我只是对无状态组件的概念感到困惑。是否创建了无状态组件和 redux 来完全替换有状态组件?在某些情况下,我只需要一个布尔标志变量或类似的东西来用于折叠/展开面板或类似功能,我认为不需要将其置于全局状态(存储)。这没有意义,对吧?
  • 我认为无状态组件适用于几乎为零逻辑的展示组件。 Redux/flux 旨在帮助推理全局应用程序状态。对于移动部件很少的组件,完全跳过 redux 是个好主意。请参阅Dan's great post,了解您的应用程序是否需要 redux/flux。在您的示例中,如果它是一个简单的布尔标志,只能由单个组件使用,而不会被应用程序中的任何其他组件读取;使用本地化的组件状态就足够了。
猜你喜欢
  • 2016-06-08
  • 2017-10-05
  • 2021-03-10
  • 2018-09-29
  • 2016-10-10
  • 2019-04-05
  • 1970-01-01
  • 2017-08-30
  • 2010-11-12
相关资源
最近更新 更多