Где я могу вызвать setState для значений 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).

Есть другой способ сделать это? Мне кажется, что это довольно общая проблема, которую решили многие ответственные нативные разработчики, но я не смог найти общепринятый способ в Интернете.

Спасибо!

Редактировать:

У меня много TextInputs, поэтому у меня есть отдельная кнопка для вызова действия по сохранению переменных:

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

Из комментариев я понимаю, что можно вызвать действие сохранения onChangeText ... но это слишком много трафика туда и обратно? Было бы лучше сохранить все переменные локально в состояние, а затем вызвать сохранение для всего сразу? Кроме того, что, если пользователь хочет «отменить» вместо сохранения? Изменения уже были бы сохранены, и мы не сможем их отменить?

вы не используете setState для изменения состояния вашего хранилища, вместо этого вы должны отправлять действия и обрабатывать действия соответствующим образом на ваших редукторах

AngelSalazar 29.03.2018 20:15

Непонятно, чего вы хотите добиться. Мне кажется, что вы меняете значение с помощью действия, а также с помощью поля ввода. Итак, вам нужно обновить его, когда значение хранилища redux изменяется И когда изменяется поле ввода. Это правильно? Тогда вы должны спросить себя, почему бы просто не менять его постоянно в магазине redux? Или наоборот.

lenkan 29.03.2018 20:18

Мне кажется, что здесь можно использовать redux store без состояния компонентов. OnMount отправляет действие для получения значения сервера, а onChange отправляет обновление значения в хранилище. Для отображаемого значения контролируйте это значением в хранилище redux

vapurrmaid 29.03.2018 20:19
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
4
3
9 654
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 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>
      )
    }
  }
Ответ принят как подходящий

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}
      />
    );
  }
}

Обратной стороной этого является то, что введенный текст не будет отображаться до тех пор, пока запрос не будет завершен.

Ты спас мне день :)

Haresh Godhani 04.01.2020 08:40

Другие вопросы по теме