Прохождение государства как реквизита - PullRequest
2 голосов
/ 02 апреля 2020

EDITED

Итак, у меня есть компонент "Счетчик", который я отображаю в своем приложении. Мое приложение содержит состояние счетчика, но как мне передать его в качестве реквизита в компонент Счетчик? На данный момент счетчик имеет свое собственное состояние, но я хочу, чтобы он использовал это состояние в приложении.

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

Универсальный счетчик:

class UniversalCounter extends Component {
  constructor(props) {
    super(props);
    const allCounter = [Counter]
    this.state = allCounter;
  }

  incrementCount() { 
    this.setState(prevState => ({ allCounter: prevState.allCounter + 1 }));
  }

  decrementCount() {
    this.setState(prevState => ({ allCounter: prevState.allCounter - 1 }));
  }

  render() {
    let { allCounter } = this.state;

    return (
      <div>
        <h2>All Counters</h2>
        <button onClick={() => this.incrementCount(allCounter)}>increase all</button>
        <button onClick={() => this.decrementCount(allCounter)}>decrease all</button>
      </div>
    );
  }

Компонент счетчика:

class Counter extends Component {
  constructor(props) {
    super(props);
    this.state = { counter: 0 };
  }

  incrementCount() {
     this.setState(prevState => ({ counter: prevState.counter+ 1 }));
  }

  decrementCount() {
    this.setState(prevState => ({ counter: prevState.counter- 1 }));
  }

  render() {
    let { counter} = this.state;

    return (
      <div>
        <h2>Count: {counter}</h2>
        <button onClick={() => this.incrementCount(counter)}>+</button>
        <button onClick={() => this.decrementCount(counter)}>-</button>
      </div>
    );
  }
}

Приложение:

class App extends Component {
  constructor(props) {
    super(props);
    this.state = { counter: 0 };
  }

  render() {
    let { counter } = this.state;

    return (
      <div className="App">
        <Counter/>
        <Counter/>
        <Counter/>
        <UniversalCounter />
      </div>
    );
  }
}

export default App;

1 Ответ

1 голос
/ 02 апреля 2020

Loft State и обработчики для ближайшего общего предка. Counter затем становится «тупым» компонентом.

Upting State Up

Counter.jsx

const Counter = ({ count, onIncrementClick, onDecrementClick }) => (
  <div>
    <h2>Count: {count}</h2>
    <button type="button" onClick={onIncrementClick}>
      +
    </button>
    <button type="button" onClick={onDecrementClick}>
      -
    </button>
  </div>
);

UniversalCounter.jsx

const UniversalCounter = () => {
  const [counters, setCounters] = useState([0, 0, 0]);

  const incrementCount = (index, c) => () =>
    setCounters(counts =>
      counts.map((count, i) => (index === i ? count + c : count))
    );

  const incrementCountAll = c => () =>
    setCounters(counts => counts.map((count, i) => count + c));

  return (
    <div>
      <h2>All Counters</h2>
      {counters.map((count, i) => (
        <Counter
          key={i}
          count={count}
          onIncrementClick={incrementCount(i, 1)}
          onDecrementClick={incrementCount(i, -1)}
        />
      ))}

      <button type="button" onClick={incrementCountAll(1)}>
        Increase All
      </button>
      <button type="button" onClick={incrementCountAll(-1)}>
        Decrease All
      </button>
    </div>
  );
};

Edit multiple counters common state

Если ( по какой-то не DRY причине вообще ) хотел визуализировать каждый счетчик индивидуально:

return (
  <div>
    <h2>All Counters</h2>

    <Counter
      count={counters[0]}
      onIncrementClick={incrementCount(0, 1)}
      onDecrementClick={incrementCount(0, -1)}
    />
    <Counter
      count={counters[1]}
      onIncrementClick={incrementCount(1, 1)}
      onDecrementClick={incrementCount(1, -1)}
    />
    <Counter
      count={counters[2]}
      onIncrementClick={incrementCount(2, 1)}
      onDecrementClick={incrementCount(2, -1)}
    />

    <button type="button" onClick={incrementCountAll(1)}>
      Increase All
    </button>
    <button type="button" onClick={incrementCountAll(-1)}>
      Decrease All
    </button>
  </div>
);
...