1,event是SyntheticEvent ,模拟出来DOM事件所有能力
2,event.nativeEvent是原生事件对象
3,所有事件,都被挂载到document上
4,和DOM事件不一样,和vue事件也不一样
label关联input用for
<form>
<label for="male">Male</label>
<input type="radio" name="sex" id="male" />
<br />
<label for="female">Female</label>
<input type="radio" name="sex" id="female" />
</form>
在react中for是关键字,所以应htmlFor
<label htmlFor="female">Female</label>
<input id="female" value={this.state.sex} onChange={this.change}/>
一般情况setState是异步事件,
自己定义dom事件的时候setState是同步事件,比如setTimeout,document.body.addEventListener('click',()=>{this.setState(count:this.state.count+1)})
setTimeout=(()=>{
this.setState({count:this.state.count+1})
},100)
react的非受控组件,在进行文件上传时候可能会用到
//在constructor里创建
this.fileInput = React.createRef()
/在组件上应用
<input defaultValue={this.state.name} ref={this.fileInput} />
<button onClick={this.alertName}>按钮</button>
//在方法alertName中可以获取
alertName=()=>{
const elem=this.fileInput.current //通过ref获取Dom节点
}
portals使用场景(应对css兼容性的时候)
1,父组件设置了overflow:hidden
2,父组件z-index值太小
3,fixed需要放在body第一层级
ReactDOM.createPortal(
<div class="app-root">{this.props.children}</div>,
document.body
)
Context 提供了一种在组件之间共享此类值的方式,而不必显式地通过组件树的逐层传递 props。
const ThemeContext = React.createContext('light'); //light为默认值
class App extends React.Component {
render() {
// 使用一个 Provider 来将当前的 theme 传递给以下的组件树。
// 无论多深,任何组件都能读取这个值。
// 在这个例子中,我们将 “dark” 作为当前的值传递下去。
return (
<ThemeContext.Provider value="dark">{/*dark为动态值,如果不填就是创建时候的默认值light*/}
<Toolbar />
</ThemeContext.Provider>
);
}
}
// 中间的组件再也不必指明往下传递 theme 了。
function Toolbar() {
return (
<div>
<ThemedButton />
</div>
);
}
//class的时候
class ThemedButton extends React.Component {
// 指定 contextType 读取当前的 theme context。
// React 会往上找到最近的 theme Provider,然后使用它的值。
// 在这个例子中,当前的 theme 值为 “dark”。
static contextType = ThemeContext;// 或者在class外写 ThemedButton.contextType = ThemeContext;
render() {
return <Button theme={this.context} />;
}
}
//函数式编程的时候
function ThemedButton (){
return(
<ThemeContext.Consumer>
{value => /* 基于 context 值进行渲染*/}
</ThemeContext.Consumer>
)
}
中级层级不需要而只有最后一级需要的时候,可以不用context
function Page(props) {
const user = props.user;
const userLink = (
<Link href={user.permalink}>
<Avatar user={user} size={props.avatarSize} />
</Link>
);
return <PageLayout userLink={userLink} />;
}
// 现在,我们有这样的组件:
<Page user={user} avatarSize={avatarSize} />
// ... 渲染出 ...
<PageLayout userLink={...} />
// ... 渲染出 ...
<NavigationBar userLink={...} />
// ... 渲染出 ...
{props.userLink}
异步组件加载(官网上的代码分割),懒加载
使用之前:(静态加载)
import OtherComponent from './OtherComponent';
使用之后:(异步加载)
const OtherComponent = React.lazy(() => import('./OtherComponent'));
如果模块加载失败(如网络问题),它会触发一个错误。你可以通过异常捕获边界(Error boundaries)技术来处理这些情况,以显示良好的用户体验并管理恢复事宜
import React, { Suspense } from 'react';
import MyErrorBoundary from './MyErrorBoundary';
const OtherComponent = React.lazy(() => import('./OtherComponent'));
const AnotherComponent = React.lazy(() => import('./AnotherComponent'));
const MyComponent = () => (
<div>
<MyErrorBoundary>
<Suspense fallback={<div>Loading...</div>}>
<section>
<OtherComponent />
<AnotherComponent />
</section>
</Suspense>
</MyErrorBoundary>
</div>
);
fallback
属性接受任何在组件加载过程中你想展示的 React 元素。你可以将 Suspense
组件置于懒加载组件之上的任何位置。你甚至可以用一个 Suspense
组件包裹多个懒加载组件
shouldComponentUpdate默认返回true,父组件更新,子组件则无条件更新,所以如果要性能优化,则可用这个钩子进行数据的深比较(耗费性能)判断返回false阻止更新,需要配合“不可变值”(比如setState中添加数组的时候不要用push。可以用immutable.js全面拥抱不可变值)
const listnew=this.state.list.slice()
this.setState({
list1:this.state.list.concat(100),//追加
list2:[...this.state.list,100],//追加
list3:this.state.list.slice(0,3),//截取
list4:this.state.list.filter((item)=>item>100),//筛选
list5:listnew,//其他操作
})
//不能直接对this.state.list 进行 push,pop,splice等
//对象
this.setState({
obj1:Object.assign({},this.state.obj1,{a:100}),
obj2:{...obj1,a:100}
})
//不能直接对this.state.obj1进行属性设置
浅比较,class组件用PureComponent,函数组件用memo
class Mouse extends React.PureComponent {
// 代码......
}
//函数式
function MyComponent(){
//代码
}
function areEqual(preProps,nextProps){
//判断
}
export default React.memo(MyComponent,areEqual){
//代码
}
高阶组件
//定义高阶组件
const HOCFactory = (Component) => {
class HOC extends React.Component {
//逻辑
render(){
return <Component { ...this.props } />
}
}
return HOC
}
//用法
export default HOCFactory(WrappedComponent)
redux单相数据流
redux的action异步,1,redux-thunk,2,redux-promise,3,redux-sage
react-redux 主要有provider,connect
hash模式(默认),如 https://abc.com/#/user/10,中后台系统,pc端的,toB
history模式,如http://abc.com/user/10,需要server端支持,因此如无特殊要求选择前者,toC
动态路由path="/project/:id",可以匹配http://abc.com/project/100,id对应100,通过userParams获取到这个id,
跳转用Link,或者用history.push(),需要引入userHistory