React Context API, установите состояние контекста из дочерних компонентов вместо передачи функций в качестве реквизита

В документации React говорится, что функцию, определенную в корневом компоненте, следует передавать в качестве реквизита дочернему компоненту, если вы планируете обновлять контекст из вложенного компонента.

Я реализовал то же самое:

import React from 'react';

const DataContext = React.createContext();

/**
 * The App.
 */
export default class App extends React.Component {
    constructor() {
        super();

        this.updateGreet = this.updateGreet.bind( this );

        this.state = {
            greet: '',
            updateGreet: this.updateGreet
        }
    }

    updateGreet() {
        this.setState({
            greet: 'Hello, User',
        });
    }

    render() {
        return (
            <DataContext.Provider value = { this.state }>
                <GreetButton />
                <DisplayBox />
            </DataContext.Provider>
        )
    }
}

/**
 * Just a button element. On clicking it sets the state of `greet` variable.
 */
const GreetButton = () => {
    return (
        <DataContext.Consumer>
            {
                ( { updateGreet } ) => {
                    return <button onClick = { updateGreet }>Greet</button>
                }
            }
        </DataContext.Consumer>
    )
}

/**
 * Prints the value of `greet` variable between <h1> tags.
 */
const DisplayBox = () => {
    return (
        <DataContext.Consumer>
            {
                ( { greet } ) => {
                    return <h1>{ greet }</h1>
                }
            }
        </DataContext.Consumer>
    )
}

Это очень простое приложение React, которое я создал для изучения Context API. Чего я пытаюсь добиться, так это определить метод updateGreet() в компоненте GreetButton вместо того, чтобы определять его внутри компонента App, поскольку функция не имеет ничего общего с компонентом App.

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

Есть ли способ достичь этого?

Вы можете передать setState и определить методы где угодно (вау - вы можете расширять возможности на лету) ... но, вероятно, вы не знаете, для чего предназначен контекст.

xadm 18.05.2019 22:05
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
1
5 201
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я бы сказал, что метод updateGreetделает имеет отношение к App, поскольку он манипулирует App состоянием.

Я не рассматриваю это как проблему, зависящую от контекста, а скорее как обычную практику реагирования на передачу функций дочерним компонентам.

Чтобы выполнить свое желание, вы мог связываете и передаете метод AppsetState провайдеру, а затем реализуете updateGreet в компоненте GreetButton, но это было бы анти-шаблоном, и я бы не рекомендовал его.

Когда я работаю с Context API, я обычно определяю свой контекст в отдельном файле и реализую собственный провайдер в соответствии со своими потребностями, передавая связанные методы и свойства вниз и используя их по всему дереву по мере необходимости.

По сути, реализуйте то, что у вас есть в App, как собственный класс ПровайдерGreetProvider. В методе рендеринга для GreetProvider просто передайте дочерние элементы:

render() {
        return (
            <DataContext.Provider value = { this.state }>
                { this.props.children }
            </DataContext.Provider>
        )
    }

Теперь вся ваша логика приветствия может жить вместе в источнике с контекстом. Используйте свой новый класс GreetProvider в App, и любой из его дочерних элементов сможет использовать его методы.

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