【问题标题】:Where do I call setState for redux values?我在哪里调用 setState 来获取 redux 值?
【发布时间】:2018-09-08 19:00:34
【问题描述】:

我对原生和异步编程反应还很陌生,并试图了解如何“同步”redux 状态值和本地状态值。

例如,我有一个文本字段“aboutMe”存储在服务器端,并使用 mapStateToProps 将其放入 props:

   const mapStateToProps = (state) => {
      return { aboutMe: state.aboutMe };
   }

在渲染中,我使用了一个 TextInput,以便用户可以编辑此字段,并且我想默认保存在服务器端的内容:

         <TextInput
          onChangeText={(aboutMe) => { 
              this.setState({aboutMe});
          }}
          value={this.state.aboutMe}
        />

基本上,我需要打电话的地方

      this.setState({ aboutMe: this.props.aboutMe });

这在哪里合适?我试图使用componentWillReceiveProps,但是没有在构造函数上调用生命周期方法,所以我需要两次setState(在构造函数和componentWillReceiveProps中)。

还有其他方法可以做到这一点吗?我觉得这是一个非常普遍的问题,很多 React Native 开发人员已经解决了,但我在网上找不到普遍接受的方法。

谢谢!

编辑:

我有很多 TextInputs,所以我有一个单独的按钮来调用操作来保存变量:

    <Button onPress={()=>{ 
      this.props.saveUserInput(this.state.aboutMe, 
      this.state.name, this.state.address, ....}}>
      <Text> Save changes </Text>
    </Button>

从 cmets 中,我了解到可以调用 onChangeText 的保存操作...但是来回的流量是否太多?将所有变量保存在本地状态,然后立即为所有内容调用保存会更好吗?另外,如果用户想“取消”而不是保存怎么办?更改已经保存,我们将无法放弃更改?

【问题讨论】:

  • 你不使用 setState 来修改你的 store 状态,而是你应该派发动作并在你的减速器上相应地处理动作
  • 不清楚你想达到什么。对我来说,您似乎正在通过操作以及输入字段更改值。因此,您需要在 redux 存储值更改和输入字段更改时更新它。它是否正确?那么你应该问自己为什么不一直在 redux 商店中更改它呢?或者反过来。
  • 在我看来你可以在这里使用没有组件状态的redux store。 OnMount,调度一个动作来检索服务器值,onChange 调度存储中值的更新。对于渲染的值,由 redux 存储中的值控制

标签: reactjs react-native redux react-redux


【解决方案1】:

1) 如果您的组件是受控组件(您需要其中的状态)并且请求确实是异步的,您必须像这样在componentWillReceiveProps 中设置状态:

class ExampleComp extends Component {
  constructor(props) {
    super(props);
    this.state = {
      aboutMe: ""
    }
  }

  componentWillReceiveProps(nextProps) {
    this.setState({
      aboutMe: nextProps.aboutMe,
    });
  }

  render() {
    return (
      <TextInput
        onChangeText={(aboutMe) => {
          this.setState({aboutMe});
        }}
        value={this.state.aboutMe}
      />
    );
  }
}

请记住,这里的关键是,从现在开始,国家必须是唯一的真相来源。

2) 另一种选择是,您可以等到父组件中的请求完成,然后在构造函数中设置aboutMe,这样您就可以避免componentWillReceiveProps。例如:

class ParentComp extends Component {

  render() {
    return (
      <div>
        {this.props.aboutMe && <ExampleComp/>}
      </div>
    );
  }
}

class ExampleComp extends Component {
  constructor(props) {
    super(props);
    this.state = {
      aboutMe: props.aboutMe
    }
  }

  render() {
    return (
      <TextInput
        onChangeText={(aboutMe) => {
          this.setState({aboutMe});
        }}
        value={this.state.aboutMe}
      />
    );
  }
}

这样做的缺点是在请求完成之前不会显示文本输入。

【讨论】:

  • 你拯救了我的一天 :)
【解决方案2】:

既然你已经编辑了你的问题,你想要实现的目标就更清楚了,所以我想解决这个问题。

您可以在组件中保留受控输入元素的状态,然后使用 redux 存储来存储持久数据并填充默认值。

class Component extends React.Component {
    constructor(props) {
       super(props)
       this.state = {
          aboutMe: props.aboutMe,
          ... // other data
       }
    }

    handleSubmit = (event) => {
      event.preventDefault() // To prevent redirect

      // Dispatch the save user input action
      this.props.dispatch(saveUserInput(this.state))
    }

    render() {
      return (
        <form onSubmit={this.handleSubmit} />
           <TextInput onTextChange={text => this.setState({...this.state, aboutMe: text}) />
           ... // input fields for other data

           // Clicking this fill trigger the submit event for the form
           <button type="submit">Save</button> 
        </form>
      )
    }
  }

【讨论】:

    猜你喜欢
    • 2017-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-12
    • 2023-04-01
    • 2021-11-25
    • 2017-09-17
    相关资源
    最近更新 更多