React Context API: значение не определено в потребительском компоненте - PullRequest
1 голос
/ 05 апреля 2020

Я пытался добавить управление состоянием в свое приложение реагирования, используя React ContextAPI, но столкнулся с проблемой. Я использую компоненты класса, идея заключается в том, чтобы получить данные из компонента, использующего Ax ios, и передать данные на приборную панель для обобщения данных.

Компонент A -> Компонент поставщика

Компонент B -> Потребительский компонент

Компонент C -> Панель инструментов -> Потребляющий компонентB

Когда я просматриваю панель мониторинга, значение состояния всегда становится неопределенным. Любые предложения о том, как я могу решить эту проблему? Благодарим вас за помощь.

пакет. json "реагировать": "^ 16.12.0", "реагировать-дом": "^ 16.12.0", "реагировать-маршрутизатор-дом": "^ 5.1 .2 "," response-scripts ":" 3.3.0 ",

Приложение. js

import React, { Component } from "react";
import "./App.css";
import { Route, Switch } from "react-router-dom";
import Dashboard from "./components/dashboard";
import ComponentA from "./components/a"
import "rsuite/dist/styles/rsuite-default.min.css";
import SomeContext from "./context/context.js";

class App extends Component {
state = {};
render() {
 return (
   <React.Fragment>
     <Sidebar />
       <Switch>
         <Route path="/dashboard" component={Dashboard} />
         <Route path="/a" component={ComponentA} />
       </Switch>
   </React.Fragment>
 );
}
}

export default App;

SomeContext. js


    import React from "react";

    const SomeContext = React.createContext();
    SomeContext.displayName = "SomeContext";


    export default SomeContext;

Компонент A -> Компонент поставщика

import React, { Component } from "react";
import axios from "axios";
import { Card, CardHeader, Table, Container, Row } from "reactstrap";
import SomeContext from "./context/context.js";
class ComponentA extends Component {
  state = {
    posts: [],
  };
  async componentDidMount() {
    const { data: posts } = await axios.get("http://localhost:5000/api");
    this.setState({ posts });
    console.log(posts);
  }

  render() {
    return (
      <div className="main-content" ref="main-content">

        <Container fluid>
          <SomeContext.Provider value={{ state:this.state }}>
            <ComponentB/>   
            **.....Some component code **

            </SomeContext.Provider>
        </Container>
      </div>
    );
  }
}

export default ComponentA;

Компонент B - Использование данных от Компонента A

import React, { Component } from "react";
import SomeContext from "./context/context.js";

class ComponentB extends Component {
static contextType = SomeContext;

  render() {
    return (
      <SomeContext.Consumer>
        {(dashboard) => (
          <div>Data: {dashboard} {console.log(dashboard)} </div>

        )}
    </SomeContext.Consumer>
        );
      }
    }

export default ComponentB;

Панель инструментов

import React, { Component } from "react";
import ComponentB from "./components/b";

class Dashboard extends Component {
  render() {
    return (
      <div className="main-content">
        <ComponentB />
      </div>
    );
  }
}

export default Dashboard;

1 Ответ

1 голос
/ 05 апреля 2020
  1. Чтобы получить работу Consumer, вы должны поместить ее под Provider. Поскольку DashBoard - это не Provider, а ComponentA, поэтому вы не можете использовать Consumer, то есть ComponentB, под DashBoard, как это.
  2. Для лучшей организации компонентов, Я рекомендую такой подход:

DashBoard будет родительским уровнем (контейнером), который отвечает за 2 вещи: выборку данных и поставщика контекста.

ComponentA теперь находится под DashBoard, что по-прежнему остается той же ролью: отображение текстовых данных. Кроме того, он также становится Consumer для извлечения данных из Provider, который сейчас равен DashBoard.

Наконец, ComponentB вложено в DashBoard, а также ComponentA, который отвечает за отображение графиков.

Пожалуйста, также рассмотрите возможность использования значимого имени для имени после ваших компонентов , Например:

ComponentA -> DisplayTextData

ComponentB -> DisplayGraph

В итоге у вас будет что-то вроде этого:

Смарт-компонент : Dashboard

Тупые компоненты : DisplayTextData, DisplayGraph

Если у вас нет Идея, что означает умный / тупой компонент, приведена в статье Дана Абрамова: здесь . Помните, что это всегда хорошая практика, когда вы должны уменьшить количество интеллектуальных компонентов и увеличить количество немых компонентов.

Чтобы ваши компоненты оставались чистыми, рассмотрите возможность перехода на Redux. Одним из многих преимуществ использования Redux для управления состоянием является то, что он позволяет избежать вызова асин c действий, побочных эффектов, таких как выборка данных внутри ваших компонентов.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...