50天用React完成50个web项目,我学到了什么?

前言: 

安装React的方法如下: 

  npm install -g create-react-app 全局安装react

  create-react-app 1 创建项目目录名称

  cd 1 切换到项目目录下

  npm start 启动react应用

1. Form Wave

效果如图所示:

学到了什么?

知识点总结:
1.CSS:CSS渐变 + 弹性盒子垂直水平居中 + CSS过渡动画 + CSS位移变换 + 关注焦点伪类选择器与同级元素选择器的用法。
2. JavaScript:字符串替换成标签 + 动态创建元素。如上述示例部分源码如下:
const createLetter = v => v.split("").map((letter,idx) => `<span style="transition-delay:${ idx * 50 }ms">${ letter }</span>`).join("");
3. map 遍历展开时要用(())而不是((){}),如下:
formArray.map((item, index) => (
    具体的代码...
))
4. transition-delay 是过渡开始等待几秒,也就是点击input时触发的动画及偏移动画,代码如下:
.div-container > form > .form-container > input:focus + label span,
.div-container > form > .form-container > input:valid + label span
{
  transform: translateY(-34px);
  color: #2396ef;
}

2. Expanding Cards

效果如图所示:

学到了什么?

 1. React的函数组件中建立数据通信,我们通常使用useState方法。react hoots的方法,它的使用方式采用数组解构的方式,如下:

const [state,setState] = React.useState(false);//useState方法的参数可以是任意的JavaScript数据类型

解构的第一个参数是我们定义并且访问的数据状态,第二个参数则是当我们需要变动数据状态时所调用的方法,其作用类似类组件中的this.setState。更详细的使用方式参考文档 useState API

2.与类组件类似的钩子函数,或者也可以理解为是函数组件的生命周期useEffect。它接收一个副作用函数effect作为参数,如下所示:

useEffect(() => {});//里面的箭头函数即副作用函数

以上示例只是做了一个简单的更换文档标题,事实上在这个副作用函数中,我们可以做很多事情,详情参考文档 useEffect API

 3.React内部有自己的一套事件机制,我们称之为合成事件。它与正常的JavaScript绑定事件很类似,但是它将事件命名方式采用了驼峰式写法,并且它也对事件对象做了一层包装,其名为SyntheticEvent。注意,这是一种跨浏览器端的包装器,我们如果想要使用原生的事件对象,可以使用nativeEvent属性,这在后面的示例中可能会涉及到。比如我们以上的事件绑定:

onClick={ changeActive.bind(this,index) }

注意这里,我们通常需要调用bind方法来将this绑定到该组件实例上,为什么要使用bind方法来绑定this呢,这是因为绑定事件的回调函数(如这里的:changeActive),它是作为一个中间变量的,在调用该回调函数的时候this指向会丢失,所以需要显示的绑定this,这也是受JavaScript自身特性所限制的。详情可参考React绑定this的原因中的解释。与之类似的是在类组件中绑定合成事件,我们也一样需要显示的绑定this指向。

4. map方法的原理。map方法迭代一个数组,然后根据返回值来对数组项做处理,并返回处理后的数组,请注意该方法不会改变原数组。比如:
[1,2,3].map(i => i <= 1);//返回[1]

jsx中渲染列表也正是利用了map方法的这一特性,并且我们需要注意的是渲染列表的时候必须要指定一个key,这是为了方便DIFF算法更好的比对虚拟DOM。

5. React中给标签添加类名,我们是写成className的,这是因为classJavaScript当做关键字。而如果我们需要动态绑定类名,可以看到,我们使用了模板字符串,在这里更像是写JavaScript,比如我们可以利用三元表达式做判断。

6. React中给标签绑定style样式,我们通常可以绑定一个对象,在React中,我们绑定动态数据就是写一对{}花括号,然后style里面的样式我们通常声明成对象来表示,比如:

style = {{background:"#fff"}}

7. 过渡效果 transition: flex .4s cubic-bezier(0.175, 0.885, 0.32, 1.275);  cubic-bezier()函数定义了一个贝塞尔曲线(Cubic Bezier),贝塞尔曲线曲线由四个点 P0,P1,P2 和 P3 定义。P0 和 P3 是曲线的起点和终点。P0是(0,0)并且表示初始时间和初始状态,P3是(1,1)并且表示最终时间和最终状态。具体参照链接 

8. 定义.active时上一层需要和 .active紧挨着,动画的核心也在于此,正常flex是0.5,点击后flex是5,如下:
App > .panel.active {
  flex: 5;
}

9. CSS:弹性盒子布局中的flex属性:让所有弹性盒模型对象的子元素都有相同的长度,且忽略它们内部的内容。

3.Progress Steps

效果如图所示:

学到了什么?

### `npm start`
# 与第一个示例所用到的知识点很类似,相关的不必做说明。接下来我们来看不一样的。
1. 父组件向子组件传递数据,我们通常都会使用props. 可以看到以上的示例,我们暴露了4个props,即:
 width
 stepItems
 currentActive
 selectStep

width 就是设置容器的宽度,stepItems就是步骤条的子组件,是一个数组,也可以在数组项中写jsx。

currentActive 就是传入当前是哪一步,是一个索引值,通常应该是数值.至于onClickItem则是子组件暴露给父组件的方法,子组件里调用时可以用this.props的方法来调用,如下:
this.props.onClickItem && this.props.onClickItem(item)
2. 类组件的生命周期.在这个类组件中,我们使用到了constructor,componentDidMount,render的生命周期钩子函数,
constructor => render => componentDidMount。从语义上来将constructor是一个构造函数,用于初始化状态(在此构造方法里需要执行super(props)这是必须的,然后需要为this.state初始化),然后初始化完成之后,我们就会渲染组件,然后才是准备挂载组件。
额外的,我们扩展一下,根据文档说明,我们可以知道详细的生命周期。React组件生命周期包含3个阶段:
挂载 => 更新 => 卸载

在组件挂载之前执行的有:
constructor => static getDerivedStateFromProps => render => componentWillMount(即将过时) => componentDidMount
在组件state变更之后,也就是更新之后,执行的有:

static getDerivedStateFromProps => shouldComponentUpdate => render => getSnapshotBeforeUpdate => componentWillReceiveProps(即将过时) => componentWillUpdate(即将过时) => componentDidUpdate
在组件卸载之后,执行的有:

componentWillUnmount
另还有错误处理的生命周期,也就是在渲染过程,生命周期,或子组件的构造函数发生错误时,会执行的钩子函数:

static getDerivedFromStateError => componentDidCatch
这里面有些生命周期我们并没有用到,有些则是几乎涵盖了我们后续的所有示例,所以我们一定要牢记组件的生命周期的顺序。
但是就这个示例而言,我们学会的应该是如何封装一个组件。
3. 全局使用颜色时可心在要css文件里来定义,如本组件的index.css,定义公共颜色时需要用到:root 样式,如下:
:root {
--color--:#dededf;
--color_active--:#2396ef;
--font_color--:#535455;
--default_color--:#fff;
}
这样组件里的css样式就可以去使用,如下:
.step-container::before {
content:"";
background-color: var(--color--);
width: 100%;
}

 4.Blurry Loading

效果如图所示:

学到了什么?

1. 在componentDidMount生命周期中创建定时器以及在componentWillUnmount中清除定时器。

2. 类组件中的this.setState更新状态。该方法接收2个参数,第一个参数则是我们的react状态,它可以是一个函数,也可以是一个对象。第二个参数则是一个回调函数。谈到这里,可能就会提到一个问题,那就是setState到底是异步还是同步? 答案如下:

答:react中的setState在合成事件和钩子函数中是"异步"的,而在原生事件和setTimeout中则是同步的。 之所以是"异步",并不代表在react内部中是"异步"代码实现的,事实上,它仍然是同步执行的一个过程。 只是合成事件和钩子函数的调用顺序在更新之前,导致在合成函数和钩子函数中没法立即拿到更新后的值,所以就形成了所谓的"异步"。 事实上,我们可以通过制定第二个参数即callback(回调函数)来获取到更新后的值。 react.js对setState的源码实现也不是很复杂,它将传入的参数作为值添加到updater也就是更新器的一个定义好的队列(即:enqueueSetState)中。 react中的批量更新优化也是建立在合成事件和钩子函数(也就是"异步")之上的,在原生事件和setTimeout中则不会进行批量更新。 比如在"异步"中对同一个值进行多次setState,依据批量更新则会对其进行策略覆盖,而如果是对不同的多个值setState,则会利用批量更新策略对其进行合并然后批量更新。 更详细的可以参考文档 setState 。

3. CSS filter属性的用法;。

4. 这里有一个非常重要的工具函数(后续有好几个示例都用到了这个工具函数)

const scale = (n,inMin,inMax,outerMin,outerMax) => (n - inMin) * (outerMax - outerMin) / (inMax - inMin) + outerMin;

这个工具函数的作用就是将一个范围数字映射到另一个数字范围。比方说,将1 ~ 100的数字范围映射到0 ~ 1之间。

5. Incrementing-counter

效果如图所示:

 

 

学到了什么?

1.字体库的使用
在index.html的header中引入 <link href="https://cdn.bootcdn.net/ajax/libs/font-awesome/5.15.3/css/all.min.css" rel="stylesheet">
使用时调用
<i className={`fab fa-3x fa-facebook`}></i>
2.react.js如何更新数组的某一项?在这里我是更新整个数组的, 我的代码如下:
startCounter () {
const counterList = [...this.state.counterList]
counterList.forEach((counter, index) => {
const updateCounter = () => {
const value = counter.value
const increment = value / 100
if (counter.initValue < value) {
// Math.ceil 取整
counter.initValue = Math.ceil(counter.initValue + increment)
counter.timer = setTimeout(updateCounter, 60)
} else {
counter.initValue = value
clearTimeout(counter.timer)
}
const list = this.state.counterList
list[index] = counter
this.setState({ counterList: list })
// this.setState({ counterList })
}
updateCounter()
})
} 

6. Animated Navigation

效果如图所示:

源码

在线案例

学到了什么

1. linear-gradient 线性渐变
新语法结构: linear-gradient([ [ [ <angle> | to [top | bottom] || [left | right] ],]? <color-stop>[, <color-stop>]+);
angle 是角度, 0deg代表东方,color-stop颜色中间点,从某个颜色到某个颜色的中间点位置,比如45度渐变,如下:
  background: linear-gradient(45deg, red, blue);
从60%的梯度线开始的渐变
有时候我们不希望一开始就出现渐变,可以从中间某个地方开始最好。为了实现这个效果,可以在你希望渐变梯度开始的地方,加上一个同样色值的颜色中间点。
  background: linear-gradient(135deg, red, red 60%, blue);
2. transition 过渡
过渡可以为一个元素在不同状态之间切换的时候定义不同的过渡效果。比如在不同的伪元素之间切换
transition: <property> <duration> <timing-function> <delay>;

transition-delay: 0s
transition-duration: 0s
transition-property: all
transition-timing-function: ease
cubic-bezier() 函数定义了一个贝塞尔曲线(Cubic Bezier)。

贝塞尔曲线曲线由四个点 P0,P1,P2 和 P3 定义。P0 和 P3 是曲线的起点和终点。P0是(0,0)并且表示初始时间和初始状态,P3是(1,1)并且表示最终时间和最终状态。
具体再查看CDN
3. transform 旋转
transform:rotate(7deg); 旋转角度7度
更多例子可以参考: https://c.runoob.com/codedemo/3391/

参考链接: https://eveningwater.github.io/#/codes/javascript/50day50project-react

https://blog.csdn.net/m0_65135687/article/details/123181033

posted @ 2022-03-20 21:00  TheYouth  阅读(205)  评论(0编辑  收藏  举报