乐趣区

关于react.js:React核心概念之状态提升

状态晋升

在 React 利用中,任何可变数据该当只有一个绝对应的惟一的‘数据源’,通常 state 都是首先增加到须要渲染数据的组件中去,而后,如果其余组件也须要这个 state,那么能够 将其晋升至这些组件的独特父组件中

比方想要实现这么一个例子:想要摄氏温度输入框与华氏度的输入框的数据同步更改,并且当摄氏水温大于 100 时会给出水会沸腾的提醒语,反之则是水不会沸腾

show you the code

在这个例子中,因为摄氏温度输入框与华氏度的输入框须要同步,因而将这两个组件须要共享的 state 向上挪动到其最近的独特父组件中,因为两个 TemperatureInput 组件的 props 均来自独特的父组件 Calculator,因而两个输入框中的内容将始终保持统一。同时如果某些数据能够由 props 或 state 推导得出,那么它就不应该存在于 state 中,比方这个例子中的 celsiusValue 和 fahrenheitValue

function Calculator(){const [temperature, setTemperature] = useState<string>('')
  const [scale, setScale] = useState<string>('c')

  const toCelsius = useCallback((fahrenheit)=>{return (fahrenheit - 32) * 5 / 9;
  },[])

  const toFahrenheit = useCallback((celsius)=>{return (celsius * 9 / 5) + 32;
  },[])

  const tryConvert = useCallback((temperature, convert)=>{const input = parseFloat(temperature);
    if (Number.isNaN(input)) {return '';}
    const output = convert(input);
    const rounded = Math.round(output * 1000) / 1000;
    return rounded.toString();},[])

  const getRightTemperature = useCallback(()=>{const celsius = scale === 'f' ? tryConvert(temperature, toCelsius) : temperature;
    const fahrenheit = scale === 'c' ? tryConvert(temperature, toFahrenheit) : temperature;
    return {
      celsius,
      fahrenheit,
    }
  },[temperature,scale])

  const handleCTempChange = useCallback((val)=>{setScale('c')
    setTemperature(val)
  },[])

  const handleFTempChange = useCallback((val)=>{setScale('f')
    setTemperature(val)
  },[])

  return(
    <>
      <TemperatureInput scale='c' temperature={getRightTemperature().celsius} onTempChange={handleCTempChange}/>
      <TemperatureInput scale='f' temperature={getRightTemperature().fahrenheit} onTempChange={handleFTempChange}/>
      <BoilingVerdict celsius={parseFloat(getRightTemperature().celsius))}/>
    </>
  )
}

interface ITprops{
  scale: 'c' | 'f',
  temperature:string,
  onTempChange:(val:string)=>void
}

function TemperatureInput(props:ITprops){
  const scaleNames = {
    c: 'Celsius',
    f: 'Fahrenheit'
  };
  return(
    <fieldset>
      <legend>Enter temperature in {scaleNames[props.scale]}:</legend>
      <input value={props.temperature} onChange={(e)=>props.onTempChange(e.target.value)}></input>
    </fieldset>
  )
}

interface IBprops{celsius:number}

function BoilingVerdict(props:IBprops){if (props.celsius >= 100) {return <p>The water would boil.</p>;}
  return <p>The water would not boil.</p>;
}

React 哲学

组合 VS 继承:在 react 中并没有发现须要应用继承来构建组件档次的状况,props 和组合提供清晰而平安地定制组件外观和行为的灵便形式,组件能够承受任意 props,包含根本数据类型,React 元素以及函数,如果想要在组件间复用非 UI 的性能,能够将其提取伟一个独自的 JS 模块

如何构建一个利用:
划分组件层级 (繁多性能准则) –> 创立一个动态页面(自上而下或者自下而上) –> 确定 state 的最小(且残缺) 示意(DRY) –> 确定 state 的地位(是否须要状态晋升) –> 增加反向数据流(回调函数传递)

DRY: Don’t Repeat Yourself, 只保留利用所需的可变 state 的最小汇合,其余数据均由它们计算产生。

退出移动版