React Router 4 - Управляемый компонент не демонтируется на коммутаторе - PullRequest
0 голосов
/ 24 января 2019

Я пытаюсь узнать, как поднять состояние с <Child/> до <Parent/> и чтобы parent управлял пользовательскими взаимодействиями, выполняющими child , (который получает состояние внизкак опора) то есть показать цвет и текст.

Я смог поднять состояние.Однако, когда я переключаю назад и вперед между маршрутами, компонент <Parent/> не перемонтируется, и его состояние остается точно таким же, каким оно было ранее установлено setState({})

const cars = [
  { name: "Ferrari", cost: "$9.000", color: "red", id: 1 },
  { name: "Porsche", cost: "$8.000", color: "black", id: 2 },
  ***
];

class Dealership extends Component {
  state = {
    cars,
    isShow: {},
    correctIndex: Math.floor(Math.random() * (cars.length - 1))
  };

  handleShuffle = () => {
    this.setState({
      cars: [...this.state.cars.sort(() => Math.random() - 0.5)],
      isShow: {}
    });
  };

  handleShow = car => {
    const { isShow } = this.state;
    console.log("isShow=", isShow);

    this.setState(currentState => ({
      isShow: { ...currentState.isShow, [car]: true }
    }));
  };

  render() {
    return (
      <>
        <Navigation />
        <Routes
          state={this.state}
          shuffle={this.handleShuffle}
          handleShow={this.handleShow}
          // isShow={this.state.isShow}
        />
      </>
    );
  }
}

export default withRouter(Dealership);

AsКак уже упоминалось выше, child <Car/> получает состояние в качестве подпорки, так что его взаимодействие с пользователем может контролироваться одним источником истины parent <Dealership />

export default class Car extends Component {
  render() {
    const { cars, shuffle, isShow, handleShow, correctIndex } = this.props;
    const correctCar = cars[correctIndex];

    const car = cars.map(car => (
      <CarList
        // {...this.state}
        isShow={isShow[car.name]}
        key={car.id}
        car={car.name}
        guess={car.cost}
        isCorrect={correctCar.cost === car.cost}
        handleShow={handleShow}
      />
    ));

    return (
      <>
        <Question key={correctCar.id} guess={correctCar.cost} />
        <button
          onClick={() => {
            shuffle();
          }}
        >
          go again
        </button>
        <ul className="car-list">{car}</ul>
      </>
    );
  }
}

Здесь <CarList/> абстрагируется:

// CarList.js
export const CarList = ({ isShow, isCorrect, car, handleShow, guess }) => {
  function getColor() {
    if (isShow) {
      const showColor = isCorrect ? "green" : "red";
      return showColor;
    }
    return "";
  }
  return (
    <li onClick={() => handleShow(car)} className={getColor()}>
      {car}
      <span className={isShow ? "show" : "hide"}>{guess}</span>
    </li>
  );
};

Как ни странно (мне), когда я переключаюсь на маршрут, который содержит свое собственное локальное состояние, т.е. <Bike/>, все работает как ожидалось (состояниевозвращается к исходному)

import React, { useState } from "react";

export const Bike = () => {
  const [color, setColor] = useState(false);

  function ChangeColor() {
    setColor(true);
  }
  return (
    <p onClick={ChangeColor}>
      Click on the <span className={color ? "red" : " "}>Bike</span>
    </p>
  );
};

Вот как я настроил мои маршруты:

// Navigation.JS
export const Navigation = () => (
  <nav>
    <ul>
      <li>
        <Link to="/">home</Link>
      </li>
      <li>
        <Link to="/car-cost">car</Link>
      </li>
      <li>
        <Link to="/bike">bike</Link>
      </li>
    </ul>
  </nav>
);

// Routes.js
export const Routes = ({ state, shuffle, handleShow, isShow }) => (
  <Switch>
    <Route
      path="/car-cost"
      render={() => (
        <Car
          {...state}
          shuffle={shuffle}
          handleShow={handleShow}
          // isShow={isShow}
        />
      )}
    />
    <Route path="/bike" render={() => <Bike />} />
    <Route path="/" component={Home} />
  </Switch>
);

Затем я обернул свое основное приложение с <BrowserRouter />, как вы видите в совокупности плюс текущаянеправильное поведение в этой кодовой песочнице

Как я могу переключаться между маршрутами с <Car/>, например <Bike/>?т.е. возврат в исходное состояние .Кроме того, Правильно ли я поднимаю и контролирую состояние здесь?

1 Ответ

0 голосов
/ 24 января 2019

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

Вы можете сохранить состояние в дочернем компоненте, которое будет сбрасывать состояние после каждого размонтирования.Однако, если вы хотите поднять состояние и по-прежнему сбрасывать его, вам придется сделать это в родительском компоненте.

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

componentDidUpdate(prevProps) {
    if (this.props.location.pathname !== prevProps.location.pathname) {
      console.log('Route change! Reset the state');
      this.setState({ isShow: {}})
    }
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...