Инициализировать состояние с помощью динамического ключа на основе реквизита в reactJS

Как инициализировать состояние с помощью динамического ключа на основе реквизита? Реквизит — это данные, полученные из внешнего источника (асинхронно). Таким образом, реквизит изменится, когда данные будут успешно загружены. Рассмотрим такой компонент.

редактировать: я хочу сделать состояние динамическим, потому что я хочу создать диалоговое окно (всплывающее окно) на основе элемента, по которому щелкнули. DialogContainer в основном это. visible prop сделает этот диалог видимым, а onHide prop скроет этот диалог. Я использую библиотеку react-md.

class SomeComponent extends React.Component {
  constructor() {
    super();
    this.state = {};
    // the key and value will be dynamically generated, with a loop on the props
    // something like:
    for (const item of this.props.data) {
      this.state[`dialog-visible-${this.props.item.id}`] = false}
    }
  }

  show(id) {
    this.setState({ [`dialog-visible-${id}`]: true });
  }

  hide(id) {
    this.setState({ [`dialog-visible-${id}`]: false });
  }

  render() {
    return (
      <div>
        {this.props.data.map((item) => {
          return (
            <div>
              <div key={item.id} onClick={this.show(item.id)}>
                <h2> Show Dialog on item-{item.id}</h2>
              </div>
              <DialogContainer
                visible={this.state[`dialog-visible-${item.id}`]}
                onHide={this.hide(item.id)}
              >
                <div>
                  <h1> A Dialog that will pop up </h1>
                </div>
              </DialogContainer>
            </div>
          );
        })}
      </div>
    )
  }
}

// the data is fetched by other component.
class OtherComponent extends React.Component {
  componentDidMount() {
    // fetchData come from redux container (mapDispatchToProps)
    this.props.fetchData('https://someUrlToFetchJSONData/')
  }
}

Затем данные передаются через Redux.

Однако, насколько я понимаю до сих пор, состояние может быть обновлено на основе реквизита с componentWillReceiveProps или новым getDerivedStateFromProps (а не на конструкторе, как указано выше). Но как это сделать в любом методе?

Пример здесь объясняется только, когда состояние инициализируется в конструкторе, и вызывается setState либо в cWRP, либо в gDSFP. Но я хочу, чтобы пара значений ключа инициализировалась динамически.

Любая помощь/подсказка будет принята с благодарностью. Пожалуйста, скажите, если мой вопрос недостаточно ясен.


person mfakhrusy    schedule 09.04.2018    source источник
comment
когда вы запускаете for loop в конструкторе, props.data должен быть предоставлен избыточностью?   -  person forJ    schedule 09.04.2018
comment
да. Так и есть.   -  person mfakhrusy    schedule 09.04.2018
comment
И вы хотите использовать состояние, предоставленное редуксом. Это то, что вы спрашиваете правильно?   -  person forJ    schedule 09.04.2018
comment
Не напрямую. Я добавил некоторые детали. Позвольте мне сначала понять ваш ответ. edit: я понимаю, как подключить состояние с помощью connect(). Но я хочу создать другое состояние с информацией из этих данных. Не напрямую. Спасибо!   -  person mfakhrusy    schedule 09.04.2018
comment
почему вы не можете создать состояния, как вы хотите, чтобы они были в самом действии? Затем вы можете просто сопоставить их с помощью функции render()   -  person forJ    schedule 09.04.2018
comment
а с точки зрения нажатия и отображения данных это может быть самостоятельным состоянием   -  person forJ    schedule 09.04.2018


Ответы (1)


import React from 'react';
import {connect} from 'react-redux';
import {yourAction} from '../your/action/path';

class YourClass extends React.Component {
    state = {};

    constructor(props){
        super(props);
    }

    componentDidMount(){
        this.props.yourAction()
    }

    render() {
        const {data} = this.props; //your data state from redux is supplied as props.

        return (
            <div>
                {!data ? '' : data.map(item => (
                    <div>{item}</div>
                ))}
            </div>
        )
    }
}

function mapStateToProps(state) {
    return{
        data:state.data //state.data if that is how it is referred to in the redux. Make sure you apply the correct path of state within redux
    }
}

export default connect(mapStateToProps, {yourAction})(YourClass)

Если вы сделаете это, <div>{item}</div> изменится при изменении состояния данных. Идея состоит в том, чтобы просто сопоставить состояние редукции с реквизитами вашего класса — вам не нужно сопоставлять реквизиты обратно с состоянием. render() автоматически прослушивает изменения реквизитов, предоставленных redux. Однако, если вы хотите каким-то образом узнать redux об изменении состояния в событиях, вы можете добавить следующие функции.

componentWillReceiveProps(newProps){
    console.log(newProps)
}

getDerivedStateFromProps(nextProps, prevState){
    console.log(nextProps);
    console.log(prevState);
}
person forJ    schedule 09.04.2018