@danil_linkins

React — Как правильно построить работу с внешним апи?

У меня есть основной "App" класс-компонент, который я отдаю в reactDOM.render.

Там у меня есть форма, в которой указан обработчик на сабмит:
<UI.FormLayout onSubmit={this.handleSubmit} v="new" allowSubmit={true} style={{ padding: "0", paddingBottom: "65px" }}>
                            <GetTest />
                            <UI.Group title="Отправление результатов">
                                <UI.List>
                                    <UI.ListItem>
                                        <UI.Input v="new" type="text" placeholder="Your name" label="Ваше имя" required />
                                    </UI.ListItem>
                                    <UI.ListItem>
                                        <UI.Input v="new" type="tel" placeholder="Phone" label="Ваш телефон" required />
                                    </UI.ListItem>
                                    <UI.ListItem>
                                        <UI.Input v="new" type="email" placeholder="E-mail" label="Ваш e-mail" required />
                                    </UI.ListItem>
                                    <UI.ListItem>
                                        <UI.Button appearance="vk-rich" type="submit" value="Submit">Завершить тест</UI.Button>
                                    </UI.ListItem>
                                </UI.List>
                            </UI.Group>
                        </UI.FormLayout>

(На UI и компоненты не обращайте внимания, просто библиотека). (GetTest - получение данных формы по API).

И есть сама функция где я делаю запрос к какому то файлу на сервере:
handleSubmit (event){
        event.preventDefault();

        console.log("submit complete");

        fetch("//some_url.com/api", {
            method: "POST",
            headers: {
                "Content-type": "application/json"
            },
            mode: "no-cors",
            credentials: "include",
            body: "response.formData()"
        })
            .then(result => result.json())
            .then(
                (result) => {
                    this.setState({
                        isLoaded: true,
                        TestResults: result,
                        activePanel: 'Results'
                    });
                },
                (error) => {
                    this.setState({
                        isLoaded: true,
                        error,
                        activePanel: 'Error'
                    });
                }
            );
    }

Но вот чего я не понимаю, если я отправил данные, скрипт на сервере их обработал и ответил какими то данными.json, то как мне потом взять эти данные, обработать и вывести?

Я пробовал делать отдельный класс под это дело, который вызывался в основном App и при успешном получении данных показывался бы, но в самом классе я создаю в state пустой массив, в котором нет тех данных, полученных с сервера да и вообще не понятно, как он у меня связан с функцией обработки сабмита. Код:
class PrintResult extends  Component {
    constructor(props) {
        super(props);
        this.state = {
            error: null,
            isLoaded: false,
            TestResults: []
        };
    }

    render() {
        const { error, isLoaded, TestResults } = this.state;
        if (error) {
            return <div>Error: {error.message}</div>;
        } else if (!isLoaded) {
            return (
                <UI.View popout={<UI.ScreenSpinner />} activePanel="spinner" header>
                    <UI.ScrollView header={{ title: 'Screen Spinner' }} id="spinner">

                    </UI.ScrollView>
                </UI.View>
            );
        } else {
            return (
                <UI.Div style={{ padding: '4px 0' }}>
                    {TestResults.map((item) => (
                        <UI.Div>
                            {item}
                        </UI.Div>
                    ))}
                </UI.Div>
            );
        }
    }
}

А результат, постоянной состояние загрузки (!isLoaded) или же просто обновляется страница.

Сам вопрос то в том, как связать все это воедино? Чтобы обработчик сабмита посылал данные, получал данные и сразу их выводил в нужном месте? Подскажите, пожалуйста, что знаете. Ценен любой совет.
  • Вопрос задан
  • 144 просмотра
Решения вопроса 1
maxfarseer
@maxfarseer
https://maxpfrontend.ru, обучаю реакту и компании
Из вопроса непонятно, где проблема.
Вы грузите данные асихнронно в том компоненте, где они вам нужны в момент componentDidMount, затем пишете их в state (с помощью this.setState) и реакт сам вызовет функцию рендер => на экране появятся ваши данные.

> Чтобы обработчик сабмита посылал данные
сделать запрос

> получал данные и сразу их выводил в нужном месте
положить в state. Если "нужное место" - это другой компонент, то значит нужно стейт держать в родителе и обновлять его с помощью функции переданной в качестве props в компонент, где данные вызываются. А другой компонент, где данные нужны, просто получает их из стейта компонента родителя в качестве props и так же отрисовывает (если приехали новые props реакт тоже вызывает render)

Ключевой момент: если ваши компоненты не знают ничего друг о друге, то вам нужно распологать данные "наверху" в общем родителе.

p.s. по-моему вы все верно начинаете разбирать, главное помнить, что в качестве props можно из родителя передать функцию (коллбэк), и через нее можно будет установить данные в стейт родителя и тд тп.

p.p.s. обычно так делать не приходится, потому что либо данные заранее живут в нужном компоненте, либо вы уже используете redux или что-то подобное.

// Parent component
...
state = {
  data: [],
}
...
myMethodInParent = (values) => {
  this.setState({data: values })
}
...
render() {
 ...
 <AnyChildren testName={this.myMethodInParent} />
}

// AnyChildren component
...

handleSubmit() => {
  this.props.testName( _ваши_данные_которые_нужно_в_стейт_родителя_ )
}
...
render() {
...
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы