React文档通读-part one

1. prosp的只读性

1.1 纯函数

个人理解:纯函数就是函数内部不去更改入参的函数,并且相同的输入,总是会得到相同的输出,并且在执行过程中没有任何副作用。

这里的副作用指的是函数在执行过程中产生了外部可观察变化。

常见的副作用
(1)发起HTTP请求
(2)操作DOM
(3)修改外部数据
(4)console.log()打印数据
(5)调用Date.now()或者Math.random()

如下代码的两个函数中,sum函数就是纯函数,因为它不会尝试更改入参,且多次调用下相同的入参始终返回相同的结果。相比之下,withdraw就不是纯函数,因为它更改了自己的入参。另外xAdd也不是一个纯函数,因为程序执行的过程中,变量a很可能会发生改变,那么改函数得到的输出就会改变。

function sum(a, b) {
   return a+b;
}

function withdraw(account, amount) {
  account.total -= amount;
}

let a = 1;
function xAdd(x) {
    return x + a;
};
xAdd(1); //2

1.1.1 纯函数的好处

(1)更容易进行测试,结果只依赖输入,测试时可以确保输出稳定
(2)更容易维护和重构,我们可以写出质量更高的代码
(3)更容易调用,我们不用担心函数会有什么副作用
(4)结果可以缓存,因为相同的输入总是会得到相同的输出

数组的很多基本方法都是纯函数,如map、forEach等等

在React中也遵循着『所有react组件 都必须要像纯函数一样保护它们的props不被更改』

1.1.2 纯函数组件

// 使用纯函数的的方式来创建组件
function Header(props) {
    return <h2>{props.text}</h2>
}

// 使用Class(类)组件的方式创建组件:
class Header extends React.Component {
  render() {
    return <h1>{this.props.text}</h1>
  }
}

纯函数组件的优点

(1)无副作用,我们不用担心副作用带来的一些难以捕捉的问题
(2)语法更简洁,可读性好,代码量相对较小,易复用
(3)占用内存小,无生命周期和状态管理,提升了性能

纯函数组件也有自己的缺点,例如:没有生命周期。所幸现在我们也已经有了很好的解决方案——react-hooks。利用hooks函数,我们可以在函数组件中使用等价于生命周期,状态管理等方法。

2. 条件渲染

你可以使用变量来存储元素,它可以做到帮助你有条件的渲染组件的一部分,而其他的渲染部分并不会因此而改变。

const renderPartOne = useMemo(
    ()=>{
       // code here
       return something;
    },[]
)

或者
const button = <LogoutButton onClick={this.handleLogoutClick} />;

3. 受控组件 & 非受控组件

React 中的组件分两种,分别是(1)将状态变化交由 React 处理的组件(2)通过ref引用获取的组件。前者是受控组件,后者则为非受控组件。非受控组件的状态在组件自身存储,需要的时候通过ref查询DOM并查找其值。

多数情况下,推荐使用受控组件实现表单。在受控组件中,表单数据由组件控制。在非受控组件中,表单组件由dom自身控制

在react中,所谓受控组件和非受控组件是针对表单而言的。受控的概念其实就是:对某个组件来说,它的值是否只能由用户设置,而不能通过代码控制。

  • 表单元素依赖于状态,表单元素需要默认值实时映射到状态的时候,就是受控组件,这个和双向绑定相似.
  • 对于受控组件,输入的值始终由React的state驱动。

3.1 受控组件

代码中有一个输入框,界面展示了输入框的内容。随着输入框内容的变化,上方文字相应变化。表单组件input的值通过onchange回调交给react处理;react获取到表单的值(e.target.value)之后,将其保存到了状态变量name中。界面展示内容通过读取组件状态name,因此name的变化触发

hello {name}
的重新渲染。

export default function App() {
    const [name, setName] = useState('');

    const handleNameChange = e => {
      setName(e.target.value);
    }
  
    return (
      <div className="App">
        <div>hello {name}</div>
        姓名:<Input onChange={handleNameChange} />
      </div>
    );
  }

3.2 非受控组件

非受控组件将数据存储在dom中,而不是组件内,这比较类似于传统的HTML表单元素。

  1. 非受控组件的值不收组件自身的state和props控制
  2. 非受控组件使用ref从dom中获取元素数据

页面中包含一个输入框和一个按钮,通过ref获取input元素的值;input值由用户改变,点击提交按钮,在handleSubmit中通过ref获取DOM 元素,进而读取输入框的值。输入框的变化并未交由组件控制,而是通过ref获取,也就是直接在dom中读取。

export default function App() {
    const eleRef = useRef(null);
    const [submitContent, setSubmitContent] = useState("");
  
    const handleSubmit = () => {
      // 通过ref获取输入框的值
      const content = eleRef.current?.value;
      setSubmitContent(content);
    };
  
    return (
      <div className="App">
        <input ref={eleRef} />
        <Button type="primary" onClick={handleSubmit}>
          提交
        </Button>
        <div>{submitContent ?? ""}</div>
      </div>
    );
  }

3.3 总结

React中的组件分为受控组件和非受控组件。

  1. 受控组件的两个要点:
  • 组件的value属性与React中的状态绑定
  • 组件内声明了onChange事件处理value的变化
  1. 非受控组件更像是传统的HTML表单元素,数据存储在DOM中,而不是组件内部,获取数据的方式是通过ref引用

  2. 一些建议:

  • 尽可能使用受控组件
  • 受控组件是将状态交由React处理,可以是任何元素,不局限于表单元素
  • 对于有大量表单元素的页面,使用受控组件会使程序变得繁琐难控,此时使用非受控组件更为明智
  • 在受控组件中,数据流是单向的(state是变化来源),因此在改变state时都应该使用setState,而不要强制赋值
  • Refs不能用于函数式组件,因为函数式组件没有实例
  • 在函数式组件内部,是可以使用Refs的

5. 参考博客

纯函数是什么?怎么合理运用纯函数?
聊一聊React中的受控组件和非受控组件

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值