查看浏览器没有改动的dom,并没有重新替换,而是复用,可能是实例vnode树(自增id),
两颗整树对比,进行diff。
state的概念出来了
有key的概念,估计diff算法都是前后对比(或者加上最大子共序列)
在修改index.js 也就是react入口文件,不论怎么修改,也是一样前台页面不会拉取js。 并且,其他文件的hmr也失效了(ws有通知),需要重新手动刷新页面。
https://codesandbox.io/s/holy-bush-b6dkh?file=/src/index.js
codesandbox
行为,是reload
页面。(vue-cli/vite
中,修改root
组件,行为一致)
HTML 标签里的元素名不区分大小写。不敏感
function render() {
return <div><test/></div>
}
class C {
constructor() {
// ...
this.state = {} // 初始化
}
// 不支持fragment
render() {
return (
<div>
<h5>props:</h5>
{this.state.date.toLocaleTimeString()}
{this.props.date}
</div>
)
}
}
和vue有不同的地方是,vue的props字段,可以自动过滤,哪些是dom参数,哪些是组件参数。
react中并不会配置成dom参数,统一当组件参数,如果需要设置组件最外层dom参数,需要手动配置。
React 事件的命名采用小驼峰式(camelCase),而不是纯小写。 使用 JSX 语法时你需要传入一个函数作为事件处理函数,而不是一个字符串。 可以直接使用this.saySomething,自动寻找classComponent的原型链。
function outSide() {
console.log('hi im here')
}
class TestClassComponent {
saySomething() {
console.log('hi')
}
render() {
return <div>
<h5 onClick={outSide}>click me</h5>
<div onClick={this.saySomething}>1</div>
</div>
}
}
TestClassComponent.prototype.saySomething = () => {
console.log('change say something')
}
// 点击1,会发现被改写
// 点击click me 会发现class风格的component,原理和es5的实现class原理都是一样的。
关于点击事件,寻找的是原型链上的,所以没有this
。也就是事件如果调用的方法,有this
,那么this
为上层(window)。
解决方法,提前bind(this)
(好迷... 可以去查看jsx转换模板)。
{/* <TestClassComponent date="123" dom-props="123" dom-int={123} /> */}
因为转换为render,child的类型可以是数组。
一切都为onChange
与value
,多选的时候,可以设置multiple属性为true
<select multiple={true} value={['B', 'C']}>
改变成为props,把方法也调成props调用,再在父组件中setState,便会更新。(期待hooks) 不然这样太麻烦了... 如果多层修改... 无限props。
function T1(props) {
return <div>{props.children}</div>
}
function T2() {
return <T1>
<div></div>
</T1>
}
jsx只是把子tree转换成了props.children
还有更灵活的方式:
function SplitPane(props) {
return (<div>{props.a}</div>)
}
function App() {
const msg = 'test'
return (<SplitPane a={<div>{ msg }</div>} />)
}
const element = (
<h1 className="greeting">
Hello, world!
</h1>
);
// 转换:等于render
const element = React.createElement(
'h1',
{className: 'greeting'},
'Hello, world!'
);
js类型的转换,只有NaN和0展示
function render() {
const number = [null, NaN, 0, "", undefined];
return (
<h1>
{number.map((v, index) => {
return (
<h2 key={index}>
{index}: {v && ""}
</h2>
);
})}
</h1>
);
// 0:
// 1: NaN
// 2: 0
// 3:
// 4:
}
jsx转换为render。方便查看代码本身。
配合Suspense
,实现loading化加载。用cra创建的项目,这项功能就是基于webpack的异步加载。
https://juejin.cn/post/6850418111599165448
被打包的文件会被分开。
命名导出: https://react.docschina.org/docs/code-splitting.html#named-exports
Context的主要使用场景在于很多不同层级的组件需要访问同样一些的数据。谨慎使用,复用组件十分烂,强绑定的传递,而且需要使用class(hooks牛逼??)。
Context 主要应用场景在于很多不同层级的组件需要访问同样一些的数据。 Context 主要应用场景在于很多不同层级的组件需要访问同样一些的数据。 Context 主要应用场景在于很多不同层级的组件需要访问同样一些的数据。 Context 主要应用场景在于很多不同层级的组件需要访问同样一些的数据。 Context 主要应用场景在于很多不同层级的组件需要访问同样一些的数据。
比vue的provide
、inject
还难用(Provide需要传递,双方都应用到)。
当 Provider 的 value 值发生变化时,它内部的所有消费组件都会重新渲染。Provider 及其内部 consumer 组件都不受制于 shouldComponentUpdate 函数,因此当 consumer 组件在其祖先组件退出更新的情况下也能更新。
这句话不太了解,shouldComponentUpdate不知道是什么,大体推测就是,value的改变强行更新consumer组件(需测)。
可以在任何生命周期中访问到他
学习到consumer 与 provider 的配合,其实也就和provide / inject一模一样了
组件是将props转换为UI,而高阶组件是将组件转换为另一个组件。
HOC其实就是把组件重复的东西收集起来,是一个概念(需要多花时间熟悉了),没有副作用
1.key
2.ref
ref并不会被当作组件参数传递,
<LogProps {...props}/>
import hoistNonReactStatic from 'hoist-non-react-statics';
function enhance(WrappedComponent) {
class Enhance extends React.Component {/*...*/}
hoistNonReactStatic(Enhance, WrappedComponent);
return Enhance;
}