将状态作为道具传递

Passing State as Props

已编辑

所以我有一个计数器按钮组件,我正在我的应用程序中呈现它。我的应用程序包含计数器的状态,但如何将其作为道具传递给计数器组件?目前 Counter 有自己的状态,但我希望它使用 App 中的状态。

我还试图在一个单独的组件中制作一个通用计数器按钮,它将 increment/decrement 复制计数器按钮。但是我有同样的问题,我不确定如何正确地将应用程序的状态作为道具传递到这个通用按钮中。

通用计数器:

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;

将状态和处理程序放样到最近的共同祖先。 Counter 然后成为 "dumb" 组件。

Lifting 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>
);

通用Counter.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>
  );
};

如果(出于某些根本不干的原因)想要单独渲染每个计数器:

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>
);