热门标签 | HotTags
当前位置:  开发笔记 > 前端 > 正文

基于react框架使用的一些细节要点的思考

下面小编就为大家带来一篇基于react框架使用的一些细节要点的思考。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

这篇文章主要是写关于学习react中的一些自己的思考:

1.setState到底是同步的还是异步的?

2.如何在子组件中改变父组件的state

3.context的运用,避免“props传递地狱”

4.组件类里有私有变量a,它到底改放在this.a中还是this.state对象中(作为属性a)呢?

1.setState到底是同步的还是异步的?

class MyComponent extends React.Component{
 constructor(props) {
  super(props)
  this.state ={
  value:0
  }
 }
handleClick = () => {
  this.setState({value:1})
   console.log('在handleClick里输出' + this.state.value);
}
render(){
   console.log('在render()里输出' + this.state.value);
return (
) } } export default MyComponent //省略渲染过程,下面也一样

在这里我们点击按钮时,调用handleClick函数,首先调用this.setState()设置value,随即把this.state.value输出,结果是什么?

你可能会想,这还不简单——“在handleClick里输出1”呗,然而你错了,它的结果为:

事实上,setState()的调用是异步的,这意味着,虽然你调用了setState({value:0}),但this.state.value并不会马上变成0,而是直到render()函数调用时,setState()才真正被执行。结合图说明一下:

你可能又会问了:要是我在render()前多次调用this.setState()改变同一个值呢?(比如value)

我们对handleClick做一些修改,让它变得复杂一点,在调用handleClick的时候,依次调用handleStateChange1 ,handleStateChange2,handleStateChange3,它们会调用setState分别设置value为1,2,3并且随即打印

handleStateChange1 = () => {
  this.setState({value:1})
  console.log('在handleClick里输出' + this.state.value);
}
handleStateChange2 = () => {
  this.setState({value:2})
  console.log('在handleClick里输出' + this.state.value);
}
handleStateChange3 = () => {
  this.setState({value:3})
  console.log('在handleClick里输出' + this.state.value);
}
handleClick = () => {
  this.handleStateChange1();
  this.handleStateChange2();
  this.handleStateChange3();
}
那么输出结果会是什么呢?如果setState是同步调用的,那么结果显然为
在handleClick里输出1
在handleClick里输出2
在handleClick里输出3
但是结果为:,证明它是异步的
这下好理解了吧,配合这幅图:

2.如何在子组件中改变父组件的state呢?

这是我们经常会遇到的问题之一,解决办法是:在父组件中写一个能改变父组件state的方法,并通过props传入子组件中
class Son extends React.Component{
 render(){
  return(
{this.props.value}
) } } class Father extends React.Component{ constructor(props){ super(props) this.state ={ value:'a' } } handleClick = () => { this.setState({value:'b'}) } render(){ return (
) } }
点击子组件Son,内容由a变成b,说明父组件的state被修改了

3.context的运用,避免“props传递地狱”
3.1假设一个比较极端的场景:你需要从你的子组件里调用父父父父父组件的属性或方法,怎么办!当组件嵌套层级过深的时候,不断地传props作为实现方式简直就是噩梦!我称之为“props传递地狱”(这个词是我瞎编的,参考自“回调函数地狱”)
我们接下来实现的是这样一个需求,把gene属性(基因)从组件GrandFather -->Father --> Son传递,如果用props传递:
class Son extends React.Component{
 render(){
  return (

我从我的爷爷那里得到了基因--{this.props.gene}

) } } class Father extends React.Component{ render(){ return () } } class GrandFather extends React.Component{ constructor(props) { super(props) this.state ={ gene:'[爷爷的基因]' } } render(){ return () } }
demo:
【(。・`ω´・)虽然听起来有点怪怪的但是大家别介意哈】
实现是实现了,但你想想,假设不是从“爷爷”组件,而是从“太太太太爷爷”组件传下来,这多可怕!不过没关系,react提供了一个叫做context(上下文)的API,你在顶层组件的context中定义的属性,可以在所有的后代组件中,通过this.context.属性去引用!让我们一睹为快:
class Son extends React.Component{
 render(){
  console.log(this.context.color);
  return (

我从我的爷爷那里得到了基因--{this.context.gene}

) } } Son.cOntextTypes={ gene:React.PropTypes.string } class Father extends React.Component{ render(){ return () } } class GrandFather extends React.Component{ getChildContext(){ return {gene:'[爷爷的基因]'} } render(){ return () } } GrandFather.childCOntextTypes= { gene: React.PropTypes.string }; export default GrandFather
demo效果同上!这个时候你发现,我们在组件和组件中都没有向下传递props,我们就从最下层的Son组件中获取了gene属性,是不是很方便!
解释下代码:
getChildContext()是你在顶层组件中定义的钩子函数,这个函数返回一个对象——你希望在后代组件中取用的属性就放在这个对象中,譬如这个例子中我希望在Son组件中通过this.context.gene取属性,所以在getChildContext()中返回{gene:'[爷爷的基因]'}
GrandFather.childContextTypes和Son.contextTypes 用于规定顶层组件和取顶层组件context的后代组件的属性类型
【注意】GrandFather.childContextTypes和Son.contextTypes 这两个对象必须要规定!否则context只能取到空对象!一开始我犯的这个错误简直让我狂吐三升血。。。。
有图有真相之context和props的区别
3.2context是否推荐使用?
虽然上面这个例子说明了context多么好用,但注意:官方并不推荐经常使用它,因为它会让你的应用架构变得不稳定(官方文档原话If you want your application to be stable, don't use context),在我看来,为什么在大多数情况下要使用props而不是实现数据流呢,因为props凭借组件和组件间严密的逻辑联系,使得你能够清晰地跟踪应用的数据流(it's easy to track the flow of data through your React components with props)当然了,如果你遇到上述的例子的情况,context还是大有裨益的
3.3需要改变context中的属性时候,不要直接改变它,而是使用this.state作为媒介,如果你试图在顶层组件的state中放入一个可变的属性你可以这样做:
getChildContext(){
  return {type:this.state.type}
}
3.4在上述我限制gene的类型时候我是这样写的:gene: React.PropTypes.string,使用了React内置的React.PropTypes帮助属性,此时我的版本为 "react": "15.4.2",在15.5的版本后这一帮助属性被废弃,推荐使用props-types库,像这样:
const PropTypes = require("Prop-Types");
GrandFather.childCOntextTypes= {
  gene: PropTypes.string
};
 
当然,在这之前你需要npm install prop-types
4.组件类里有私有变量a,它到底改放在this.a中还是this.state对象中(作为属性a)呢?
这得根据它是否需要实时的重渲染决定,如果该变量需要同步到变化的UI中,你应该把它放在this.state对象中,如果不需要的话,则把它放在this中(无代码无demo)

以上这篇基于react框架使用的一些细节要点的思考就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。


推荐阅读
  • 基于Node.js、Express、MongoDB和Socket.io的实时聊天应用开发
    本文详细介绍了使用Node.js、Express、MongoDB和Socket.io构建的实时聊天应用程序。涵盖项目结构、技术栈选择及关键依赖项的配置。 ... [详细]
  • 深入理解Vue.js:从入门到精通
    本文详细介绍了Vue.js的基础知识、安装方法、核心概念及实战案例,帮助开发者全面掌握这一流行的前端框架。 ... [详细]
  • 前端开发中的代码注释实践与规范
    本文探讨了前端开发过程中代码注释的重要性,不仅有助于个人清晰地回顾自己的编程思路,还能促进团队成员之间的有效沟通。文章将详细介绍HTML、CSS及JavaScript中的注释使用方法,并提出一套实用的注释规范。 ... [详细]
  • 在树莓派Ubuntu(ARM64)上安装Node.js
    本文详细介绍了如何在树莓派Ubuntu系统(ARM64架构)上安装Node.js,包括下载、解压、移动文件以及创建软链接等步骤。 ... [详细]
  • 本文将详细介绍如何在Bootstrap 5中使用五种不同的表单控件样式,包括输入框、选择器和文本区域等元素。 ... [详细]
  • Node.js 入门指南(一)
    本文介绍了Node.js的安装步骤、如何创建第一个应用程序、NPM的基本使用以及处理回调函数的方法。通过实际操作示例,帮助初学者快速掌握Node.js的基础知识。 ... [详细]
  • Webpack中实现环境与代码的有效分离
    本文探讨了如何在Webpack中有效地区分开发与生产环境,并实现代码的合理分离,以提高项目的可维护性和加载性能。 ... [详细]
  • 本文通过探讨React中Context的使用,解决了在多层级组件间传递状态的难题。我们将详细介绍Context的工作原理,并通过实际案例演示其在项目中的具体应用。 ... [详细]
  • Vue 项目构建与部署指南
    本文将指导您完成Vue项目的构建和部署过程,包括环境搭建、项目初始化及配置、以及最终的部署步骤。 ... [详细]
  • 本文详细探讨了Xshell6评估版到期后无法使用的常见问题,并提供了有效的解决方案,包括如何合法购买授权以继续使用。 ... [详细]
  • 利用 Jest 和 Supertest 实现接口测试的全面指南
    本文深入探讨了如何使用 Jest 和 Supertest 进行接口测试,通过实际案例详细解析了测试环境的搭建、测试用例的编写以及异步测试的处理方法。 ... [详细]
  • 本文探讨了前端包管理器的核心功能,包括注册机制、文件存储、上传下载、以及依赖分析等关键特性,并介绍了几种流行的前端包管理工具。 ... [详细]
  • 了解如何快速搭建属于自己的个人博客,无需编程基础,适合Mac和Windows用户。通过本文,您将学会使用GitHub Pages和Hexo构建一个完全自主的在线空间。 ... [详细]
  • 掌握Vue与Vue CLI版本查询方法
    在开发过程中,准确了解当前项目中Vue及Vue CLI的具体版本对于解决问题至关重要。本文将详细介绍如何通过简单步骤快速查询Vue框架及其CLI工具的版本信息。 ... [详细]
  • 如何使用Ionic3框架创建首个混合开发应用
    混合开发是指结合原生(Native)与网页(Web)技术进行移动应用开发的方法。本文将详细介绍如何利用Ionic3这一流行的混合开发框架,从环境搭建到创建并运行首个应用的全过程。 ... [详细]
author-avatar
QingGang
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有