Как инициализировать состояние для каждого элемента в массиве ReactJS - PullRequest
0 голосов
/ 03 мая 2019

Новое в React и создании приложения географии. У меня есть множество континентов uniqueRegions = ['Asia', 'America', 'Europe', 'Africa', 'Oceania', 'Polar'] в моих реквизитах как this.props.uniqueRegions. В моем компоненте я хочу установить состояние свойства visible на каждом из этих континентов. Я мог бы жестко закодировать это, но я не хочу этого делать. Как я могу это сделать?

Я попытался использовать оператор распространения как таковой

state = {
  [ ...this.props.uniqueRegions]: {visible: 5}
    };

но это, очевидно, неверный синтаксис.

Также я попытался инициализировать свойство visible в setState, но оно всегда возвращает неопределенное значение.

loadMore = (region) => {
        console.log(this.state[region])
        if(this.state[region])
        this.setState(prevState => ({
            [region]: {visible: 5}
        }))
    }

Ниже показано, как данные моего региона передаются и в настоящее время установлены в состояние.

filterRegion = (region) =>{
        if(region !==undefined ){
            this.setState({
                [region]: {countries: ['']}
            })
          return Axios
           .get('https://restcountries.eu/rest/v2/region/' + region)
           .then(res => {
             if(res.status === 200 && res !== null){
              this.setState(prevState =>({
                [region]: {...prevState[region],
                    countries: (res && res.data || [])} 
              }))
              } else {
               throw new Error('No country found');
             }
             })
             .catch(error => {
               console.log(error)
               return []
             });
         };
        };

    loadMore = (region) => {
        console.log(this.state[region])
        if(this.state[region])
        this.setState(prevState => ({
            [region]: {visible: 5}
        }))
    }

    render(){
        const handleRegion =(region) =>{
            this.filterRegion(region);
            if(this.state[region] && this.state[region].open){
                this.setState(prevState =>({
                    [region]: {...prevState[region],
                        open: false
                    }
                  }))
            } else {
                this.setState(prevState =>({
                    [region]: {...prevState[region],
                        open: true
                    }
                  }))
            }
        }

Мне удалось установить свойства для определенного региона, то есть [регион] .open, но не могу заставить его работать с видимым.

РЕДАКТИРОВАТЬ / РЕШЕНИЕ ПРОБЛЕМЫ

Поработав с Юниусом, я изменил свой код. Что для меня исправило, так это установив переменную, которая содержала все свойства для каждого элемента массива, которые я хотел, добавив их в массив, а затем установив весь массив как состояние, используя оператор распространения.

        if (!regions) {
            console.log('no regions')
          return;
        }
        if(regions) 
        console.log(regions);
        const regionsState = {};

        regions.forEach((region, index) => {
            if(this.state[region] && this.state[region].countries[0]){
                regionsState[region] = { visible: 5, countries: this.state[region].countries, open: false};
            } else {
                this.filterRegion(region);
                regionsState[region] = { visible: 5, countries: [], open: false};
            }
        });

        // set state here outside the foreach function
         this.setState((prevState => ({
           ...regionsState
         })))
      };

Наконец, я не смог получить данные для правильной инициализации. Сначала я загружал данные одним кликом, но это не идеально и не реалистично; выполнение кода в componentDidMount не сработает после загрузки реквизита. Решением для меня было запустить функцию в componentDidUpdate . Мое состояние теперь правильно инициализируется. Еще раз спасибо Юний за помощь!

Ответы [ 3 ]

0 голосов
/ 03 мая 2019

Вы можете использовать простой пустой объект в состоянии:

state = {
    visibleRegions: {}
}

Сделать регион видимым так же просто, как определить свойство с регионом, как ключ

visibleRegions[region] = true;

Условие !visibleRegions[region] будет охватыватьundefined и false ... !!visibleRegions[region] для видимого состояния.

0 голосов
/ 03 мая 2019

Я сделал это с помощью флажка, вы можете адаптировать его по своему усмотрению к любому элементу, это тот же принцип, я не знаю, ищите ли вы это, потому что я не уверен, что получил ваш вопрос, но я надеюсь, по крайней мере, это дает вам представление. Возьми свой массив из реквизита const {myData} = this.props Удачи:)

`

класс Geo расширяет Компонент { состояние = { видимый: ложь, uniqueRegions: ['Азия', 'Америка', 'Европа', 'Африка', 'Океания', 'Полярный'] };

handleChecked = () => {
    this.setState({
        visible: !this.state.visible
    });
};
render() {
    const { uniqueRegions } = this.state;
    return (
        <div>
            <input type="checkbox" onChange={this.handleChecked} value={uniqueRegions} />

            {uniqueRegions.map(region => {
                if (this.state.visible) {
                    return (
                        <p>
                            these are my regions {region}
                        </p>
                    );
                } else {
                    return null;
                }
            })}
        </div>
    );
}

}

экспорт по умолчанию Geo; `

0 голосов
/ 03 мая 2019

создайте новый объект и добавьте каждый регион к объекту как свойство.

setDynamicRegions = regions => {
  if (!regions) {
    return;
  }

  const regionsState = {};

  regions.forEach((item, index) => {
    regionsState[item] = { visible: 0 };
  });

  //   this.setState({
  //     regionsState: regionsState
 //   });
};

const uniqueRegions = [
    "Asia",
    "America",
    "Europe",
    "Africa",
    "Oceania",
    "Polar"
    ];

    const setDynamicRegions = regions => {
    if (!regions) {
        return;
    }

    const regionsState = {};

    regions.forEach((item, index) => {
        regionsState[item] = { visible: 0 };
    });

    //   this.setState({
    //     regionsState: regionsState
    //   });
    console.log(regionsState);
    };

    setDynamicRegions(uniqueRegions);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...