Поднять состояние между компонентами в реакции

У меня проблема со связью между реагирующими компонентами. Я хочу передавать значения между компонентами «ProductNameSave.js» в «readJson.js». Значения из ProductNameSave.js получены из компонента windowForm.js. Из-за этой структуры ("windowForm.js" -> "ProductNameSave.js" -> "readJson.js") я думаю, что "ProductNameSave.js" является "источником истины". Вот компоненты. "windowForm.js"

import React from 'react';
import Input from '@material-ui/core/Input';
import UploadPicture from './UploadPicture.js';

export default class FormWindow extends React.Component{
    state  = {
        U_Factor:'',
        Solar_Heat_Gain_Coefficient:'',
        Visible_Transmittance:''
    };

    change = e =>{
        this.setState({
            [e.target.name]: e.target.value
        });
    };

    onSubmit= e =>{
        e.preventDefault();
        this.props.onSubmit(this.state);
        this.setState({
            U_Factor:'',
            Solar_Heat_Gain_Coefficient:'',
            Visible_Transmittance:''
        });
    };

    render(){
        return(
            <form className = "productForm">
                <Input 
                    name = "U_Factor"
                    placeholder = "U-Factor" 
                    value = {this.state.prodValue1} 
                    onChange = {e => this.change(e)}
                />
                <br />
                <Input 
                    name = "Solar_Heat_Gain_Coefficient"
                    placeholder = "Solar Heat Gain Coefficient"
                    value = {this.state.prodValue2} 
                    onChange = {e => this.change(e)}
                />
                <br />
                <Input 
                    name = "Visible_Transmittance"
                    placeholder = "Visible Transmittance" 
                    value = {this.state.prodValue3} 
                    onChange = {e => this.change(e)}
                />
                <br />
                <UploadPicture/>
               <button onClick = {e => this.onSubmit(e)}>Submit</button>
            </form>    
        )
    }
}

"ProductNameSave.js":

import React from 'react';
import FormWindow from './windowForm.js';


export default class ProductNameSave extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      field:'', 
      open: false
    };
  }

  state = {
    fields:{}
  };

  handleChance(fields){
    this.setState({fields})
  }

  onSubmit = (fields) => {
    this.setState({fields});
    console.info('App component got: ', fields);
  };

  render() {
    const fields = this.state.fields
    return (
      <div>
        <FormWindow  onSubmit  = {fields => this.onSubmit(fields)} />
      </div>
    );
  }
}

"readJson.js":

import React from 'react';
import MyAppChild from './readJsonChild.js';
import data from '../../model/data/ProductData/Material.json';
import ProductNameSave from '../ProductList/ProductNameSave.js';

export default class MyApp extends React.Component {

  constructor(props) {
    super(props);
    this.handleChangeEvent = this.handleChangeEvent.bind(this);
    this.state = {fields: ''};
  }

  handleChangeEvent(fields) {
    this.props.onValueChance({fields});
  }

  render() {
      const fields = this.props.fields;
      var json2 = data[0]      
      var arr = [];
      Object.keys(json2).forEach(function(key) {
        arr.push(json2[key]);
      });
    return 
      <ul>{arr.map(item => <MyAppChild key = {item.Name} Name = {item.Name} Roughness = {item.Roughness} Thickness = {item.Thickness} />)}</ul>;
      <ul><ProductNameSave onChance  = {fields => this.handleChangeEvent(fields)}/></ul>;
  }
}

readJson.js получает значения из отдельного компонента. Цель состоит в том, чтобы передать значения из windowForm.js через ProductNameSave в readJson, чтобы заменить значения в reaJson новыми значениями из ProductNameSave. Если я запускаю код, я получаю следующую ошибку: Ошибка: MyApp.render (): должен быть возвращен действительный элемент React (или null). Возможно, вы вернули undefined, массив или другой недопустимый объект.

Есть ли у кого-нибудь идеи, как я могу решить эту проблему?

Заранее большое спасибо!

Как сделать HTTP-запрос в Javascript?
Как сделать HTTP-запрос в Javascript?
В JavaScript вы можете сделать HTTP-запрос, используя объект XMLHttpRequest или более новый API fetch. Вот пример для обоих методов:
0
0
924
3

Ответы 3

Проблема в readJson.js. То, как этот компонент возвращает JSX, неверен. В React 15 каждый компонент JSX-элемента должен быть заключен в div или span и т. д.

Проверьте обновленный код ниже

import React from 'react';
import MyAppChild from './readJsonChild.js';
import data from '../../model/data/ProductData/Material.json';
import ProductNameSave from '../ProductList/ProductNameSave.js';

export default class MyApp extends React.Component {

  constructor(props) {
    super(props);
    this.handleChangeEvent = this.handleChangeEvent.bind(this);
    this.state = {fields: ''};
  }

  handleChangeEvent(fields) {
    this.props.onValueChance({fields});
  }

  render(){
    const fields = this.props.fields;
      var json2 = data[0]      
      var arr = [];
      Object.keys(json2).forEach(function(key) {
        arr.push(json2[key]);
      });
    let children = [];
    arr.map((item, i) => {
        children.push(<MyAppChild key = {item.Name} Name = {item.Name} Roughness = {item.Roughness} Thickness = {item.Thickness} />);
    });
return(
    <div>
        <ul>
        {children}
        </ul>
        <ul><ProductNameSave onChance  = {fields => this.handleChangeEvent(fields)}/></ul>
    </div>
    )
}
}

если ваш компонент возвращает один элемент jsx, тогда их не нужно заключать между div или span, если более одного элемента jsx, тогда они должны быть заключены.

Привет, Хемадри, твой код работает. Но не могу конфигурировать значения из файла readJson.js. Но я хочу сопоставить значения, которые у меня есть в json2, с новыми значениями, которые я получаю из файла productNameSave.js

CUR 16.08.2018 13:06

Я дал решение следующей проблемы: «Ошибка: MyApp.render (): должен быть возвращен действительный элемент React (или null). Возможно, вы вернули undefined, массив или другой недопустимый объект». Теперь это новая проблема, что вы имеете в виду, когда не можете настроить значения, которые я не получаю

Hemadri Dasari 16.08.2018 13:09

Ты прав! Большое спасибо! Новая проблема заключается в том, что я хочу сопоставить значения, которые у меня есть в json2, с новыми значениями, которые я получаю из файла productNameSave.js.

CUR 16.08.2018 13:12

Н.П. Вы говорите, что получаете значения из файла productNameSave.js. Как я вижу, productNameSave.js вызывает (отображает) FormWindow только onSubmit = {fields => this.onSubmit (fields)}, а вы передаете только функцию обработчика. Так как же получить значения из productNameSave.js?

Hemadri Dasari 16.08.2018 13:28

ProductNameSave вызывает через значения onSubmit из файла windowForm.js. Через файл windowForm.js я ввожу значения в интерфейсе пользователя. Я выполнил инструкции поднять состояние, чтобы передать значения из ProductNameSave.js в readJson.js. В этом руководстве они могут указать реквизиты, а также используют функцию handelChance. Но у меня не работает. И я не знаю почему...

CUR 16.08.2018 13:36

Вы также можете использовать <React.Fragment>, если используете версию React> 16. Это позволяет избежать добавления другого элемента в DOM только для группировки других элементов JSX.

<React.Fragment>
    <ul>{arr.map(item => <MyAppChild key = {item.Name} Name = {item.Name} Roughness = {item.Roughness} Thickness = {item.Thickness} />)}</ul>;
    <ul><ProductNameSave onChance  = {fields => this.handleChangeEvent(fields)}/></ul>;
</React.Fragment>

Ссылка: Документ ReacJS для фрагмента.

Существует еще одна сокращенная версия ReactJS, которая пока не поддерживается другими инструментами. То же самое можно прочитать на приведенной выше странице документа.

Не пытайтесь поднять состояние из windowForm.js через ProductNameSave до readJson, это антипатерн. Вместо этого вы можете сделать следующее:

  1. Определите состояние в родительском компоненте (в вашем случае это, вероятно, компонент readJson), а также определите метод, который изменит состояние и будет передан дочернему компоненту (в вашем случае windowForm.js). Как только вы определите такой метод и передадите его дочернему компоненту, вы сможете вызвать этот метод внутри дочернего компонента, и этот метод изменит состояние в родительском компоненте.

ИЛИ

  1. Используйте Redux и храните свои данные в глобальном состоянии. Эти данные будут доступны во всех ваших компонентах.

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