有没有办法在没有setState的情况下重新渲染功能性React.js组件?

时间:2019-02-19 11:17:15

标签: javascript reactjs react-redux

我有一个功能性的React组件,在更改滑块的位置后需要重新渲染。由于我使用Redux来处理状态,因此我不需要使用React,因为对我来说这将是解决问题的一种拙劣方法。有没有一种实际的方法可以在不将我的组件转换为经典组件的情况下重新呈现该组件onChange?

import React from "react";
import { Radio, RadioGroup } from "@material-ui/core";
import Slider from "@material-ui/lab/Slider";

const consoleLog = e => {
  console.log(e.target.name, ": ", e.target.value);
};

const handleData = question => {
  switch (question.type) {
    case "fv":
      return (
        <p
          className="range-field"
          style={{ width: 25 + "%", margin: 25 + "px" }}
        >
          <Slider
            value={25}
            min={question.min}
            max={question.max}
            onChange={consoleLog}
          />
        </p>
      );
  }
};

const Answers = props => {
  return <div>{handleData(props.data)} </div>;
};

export default Answers;

3 个答案:

答案 0 :(得分:1)

滑块位置实际上是一种状态。 UI组件(Slider)是无状态的,并且期望父组件(Answers)使用单向数据流处理其状态。

如果最好将UI状态保存为全局状态,则可以使用Redux处理滑块状态。

否则,应使用本地状态。可以将一个组件转换为一个组件以使用setState,使用它并不容易,因为这实际上是一种状态。或功能组件可以使用React 16.8挂钩:

const Answers = props => {
    const [slide, setSlide] = useState(25);
    const onChange = useCallback(e => setSlide(e.value), []);
    const handleData = question => {
      switch (question.type) {
        case "fv":
          return (
            <p
              className="range-field"
              style={{ width: 25 + "%", margin: 25 + "px" }}
            >
              <Slider
                value={slide}
                min={question.min}
                max={question.max}
                onChange={onChange}
              />
            </p>
          );
      }
    };

    return <div>{handleData(props.data)} </div>;
};

useState保留组件渲染之间的滑块状态的情况下,useCallback防止不必要的Slider重新渲染。

答案 1 :(得分:0)

您可以使用forceUpdate方法强制重新渲染。

文档:https://facebook.github.io/react/docs/component-api.html

答案 2 :(得分:0)

想通了!所以我使用React钩子,但是由于我使用的是Material-ui,因此我发现该值随事件一起传递。因此,使用estus提供的代码,我在onChange函数上添加了值作为附加参数,以便获取值。

const Answers = props => {
const [slide, setSlide] = useState(props.data.min);
const onChange = useCallback((e, value) => setSlide(value), []);
const handleData = question => {
  switch (question.type) {
    case "fv":
      return (
        <p
          className="range-field"
          style={{ width: 25 + "%", margin: 25 + "px" }}
        >
          <Slider
            value={slide}
            min={question.min}
            max={question.max}
            onChange={onChange}
          />
        </p>
      );
  }
};

return <div>{handleData(props.data)} </div>;
};