React: Импорт состояния из одного компонента в другой компонент?

Компонент Link загружен в компонент Foot (см. Внизу).

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

Кажется, я не могу изменить состояние, если оно не находится в одном компоненте, но загрузка этого состояния в ul довольно странная.

Компонент связи

import React, { Component } from 'react';

import Home from './Home';
import Characters from './Characters';
import Plot from './Plot';
import Scenes from './Scenes';
import Notes from './Notes';

class Link extends Component {
  constructor() {
    super();
    this.state = {page: <Home />}
  }

  loadPage = (page) => {
    this.setState({page: page})
  }

  render() {
    const links = [
      {
        title: 'Home',
        page: <Home />
      }, 
      {
        title: 'Characters',
        page: <Characters />
      }, 
      {
        title: 'Plot',
        page: <Plot />
      }, 
      {
        title: 'Scenes',
        page: <Scenes />
      }, 
      {
        title: 'Notes',
        page: <Notes />
      }
    ]

    const link = links.map((item, index) => {
      return (
        <li key = {index}>
          <button onClick = {() => this.loadPage(item.page)}>
            {item.title}
          </button>
        </li>
        )
    })
    return (
      <ul className = "Link">
        {link}
      </ul>
    );
  }
}

export default Link;

Компонент содержимого

import React, { Component } from 'react';

import Link from './Link';

class Content extends Component {

  render() {
    return (
      <div className = "Content">
        {/*this.state.page goes here*/}
      </div>
    );
  }
}

export default Content;

Компонент ноги (не очень актуально, но общие ссылки пойдут сюда

import React, { Component } from 'react';

import Link from './Link'

class Foot extends Component {

  render() {
    return (
      <footer className = "Foot">
        <Link />
      </footer>
    );
  }
}

export default Foot;
Поведение ключевого слова "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) для оценки ваших знаний,...
0
0
1 067
2

Ответы 2

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

const {Provider, Consumer} = React.createContext(defaultValue);

Используйте поставщика в компоненте Link.

<Provider value = {/* some value */}>

Используйте потребителя в своем информационном компоненте.

<Consumer>
  {value => /* render something based on the context value */}
</Consumer>

Подробности смотрите в официальной документации. https://reactjs.org/docs/context.html#reactcreatecontext

Вам нужно будет использовать Props, чтобы подтолкнуть щелкнувшие ссылки к родительскому объекту. Итак, в следующем примере я предполагаю, что Content будет родительским компонентом.

import React, { Component } from 'react';

import Home from './Home';
import Characters from './Characters';
import Plot from './Plot';
import Scenes from './Scenes';
import Notes from './Notes';

class Link extends Component {
  // this.props.menuClicked(item.page) 
  // hits the menuClicked props of Foot Component
  render() {
    return (
      <ul className = "Link">
        {links.map( (item, index) => {
          return (
            <li key = { index }>
              <a href = "#" onClick = { () => this.props.menuClicked(item.page) }>
                { item.title }
              </a>
            </li>
          )
        })}
      </ul>
    );
  }
}

export default Link;

Компонент Foot является родительским элементом Link Component.

import React, { Component } from 'react';
import Link from './Link'
class Foot extends Component {
  constructor() {
    super();
    this.loadPage = this.loadPage.bind(this)
  }

  loadPage = (page) => {
    // notice this also pushes the page clicked up to the parent component which is 
    // the Content Component
    this.props.changePage(page);
  }

  render() {
    return (
      <footer className = "Foot">
        <Link menuClicked = { () => this.loadPage(page) } />
      </footer>
    );
  }
}

export default Foot;

И основным родительским элементом (прародителем компонента Link) будет компонент Content.

// Content
import React, { Component } from 'react';
import Footer from './Footer';
import Home from './Home';
import Characters from './Characters';
import Plot from './Plot';
import Scenes from './Scenes';
import Notes from './Notes';
import Link from './Link';

class Content extends Component {
  constructor() {
    super()
    // default page
    this.state = { page: 'Home' }
    this.changePage = this.changePage.bind(this);
  }
  // called everytime the Link is clicked
  changePage(newPage) {
    this.setState({
      page: newPage
    })
  }

  render() {
    const links = [
      {
        title: 'Home',
        page: <Home />
      }, 
      {
        title: 'Characters',
        page: <Characters />
      }, 
      {
        title: 'Plot',
        page: <Plot />
      }, 
      {
        title: 'Scenes',
        page: <Scenes />
      }, 
      {
        title: 'Notes',
        page: <Notes />
      }
    ];
    let contentToLoad = null,
      pageToLoad = this.state.page;
    links.forEach( (item) => {
      if (item.title == pageToLoad) {
        contentToLoad = item.page;
      }
    });

    return (
      <div className = "Content">
        { contentToLoad }
        <Footer changePage = { this.changePage } />
      </div>
    );
  }
}

export default Content;

На основе ссылки, по которой щелкнули в компоненте ссылки, соответствующий контент будет загружен в компонент контента. Как вы можете видеть, Foot Component просто передает то, что Link Component подталкивает к Content Component, вы можете либо полностью отказаться от Foot Component, либо использовать то, что предлагает @ShubamGupta, то есть использовать контекстные API. С ContextAPI у вас могут быть провайдер и потребитель, и если вы перейдете по ссылке, которую он отправил, вы сможете передавать контент непосредственно из компонента ссылки в компонент контента.

Содержание и Ступня на самом деле являются братьями и сестрами, но Ссылка является дочерним элементом Ступня
00Saad 21.09.2018 23:30

В этом случае Ссылка должен будет подтолкнуть выбор к родительскому элементу Ступня, и этот родитель будет подталкивать выбор страницы к Содержание или еще лучше, отправить страницу как дочернюю к Содержание<Content>{ pageToLoad }</Content>, а компонент Содержание просто отображает дочерние элементы как render() { return (<div>{ this.props.children }</div> }

Tenzin Kunkyab 23.09.2018 16:27

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