先放一个react中文网站在这
虚拟dom就是程序员根据页面标签通过js创建dom树
之后通过新旧dom树进行对比,看dom树哪个部分变化,
从而只改变 改变的部分
diff算法我理解大概就是,把js模拟的虚拟dom和原有的dom节点进行对比;把他们分为很多层级,每个层级和相应的层级对比;就比如一个树的最顶的树叶和另一个树的最顶的树叶对比,是一一对应的
具体解析可以看看阮一峰大神的文章
cdn方法引入不推荐
<!-- 加载 React。-->
<!-- 注意: 部署时,将 "development.js" 替换为 "production.min.js"。-->
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
// 使用JSX
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
npm 方法安装推荐 在这之前一定要确定你已经安装node环境
cnpm install -g create-react-app // 安装react脚手架
cnpm i -g create-react-app //install可以简写为i
// 创建项目
create-react-app 项目名称
// 我这里安装出错是因为没下载cnpm包,下载并同时设置淘宝镜像
npm install -g cnpm --registry=https://registry.npm.taobao.org
注意这里可能会报错,你可以试试以管理员模式下载 mac是sudo
ReactDom.render()传入两个函数,第一个是对象函数,也就是dom;第二个是dom需要显示的地方
react和vue的结构大相径庭;都是有静态资源和配置文件和node依赖等等;但是react的组件是.js形式所以我们要介绍重要的组成JSX
let h = <h1>hello word</h1> // 这是jsx语法
**let ph = <h2>hello</h2> <p>word</p>** // 会报错
let hp = <h2>hello <p>word</p></h2> // 这样是对的 只能有一个根元素
let word='hello word'
let h= <div>{word}</div>
ReactDom.render(h,
document.getelementById('root')
)
//class.css 如下
.word{
width:100%;
height:200px;
background:'blue'
}
.color{
color:'red'
}
//index.js
import './class.css'
let classname='word'
let div= <div className={'color'+word} ></div>
'background-color':'red'
let backAndTextColor = {
backgroundColor:'red',
color:'white',
fontSize:40
};
{/* jsx中调用 */}
<div style={backAndTextColor}>看背景颜色和文字颜色</div>
{ /* 也可以在jsx中直接写样式,但是一定是对象格式 */ }
<div style={{backgroundColor:'red',color:'white',fontSize:40}}>看背景颜色和文字颜色</div>
//函数组件
function Renders(props){
console.log(props) // {hname:'哈哈哈哈'}
return (
<div> Hello Word </div>
)
}
{ /* 简单的传值 */ }
ReactDom.render(<Renders hname='哈哈哈哈' />,docment.getelementById('root'))
// 类组件
class Hello extends React.Component{
{/* 类组件必须有render函数 */}
render(){
console.log(this) {/*这里this是这个组件*/}
return(
<div>hello hi</div>
)
}
}
ReactDom.render(<Hello hi='hi' />,document.querySelector('#root'))
class Clock extends React.component{
// construtor和super可以被省略不写,或者必须写全套
constructor(props){ // es6语法 extends要配合constructor
super(props);
this.state={
word:'hello'
}
},
render(){
retrun(
<div>{this.state.word}</div>
)
}
}
ReactDom.render(<Clock />,document.querySelector('#root'))
setState({})
this.state
,会等同步任务执行完,再去更新this.stateclass Parent extends React.component{
constructor(props){
super(props);
this.state={
word:'hello'
}
},
render(){
retrun(
<Chrild word={this.state.word} />
)
}
}
ReactDom.render(<Parent />,document.querySelector('#root'))
// 子组件
class Parent extends React.component{
constructor(props){
super(props);
},
render(){
retrun(
<div>这是父组件传的值{this.props.word}</div>
)
}
}
// 父组件
class Parent extends React.component{
constructor(props){
super(props);
this.state={
word:'hello'
}
},
render(){
retrun{
<Chrild word={this.changeState} />
}
}
// 也可以把下面函数改为箭头函数
this.changeState=this.changeState.bind(this)
changeState(data){
this.setState({
word:data
})
}
}
ReactDom.render(<Parent />,document.querySelector('#root'))
// 子组件
class Parent extends React.component{
constructor(props){
super(props);
this.state={
val:'888'
}
},
render(){
retrun(
<div>
这是父组件传的值{this.props.word}
<p>改变父组件的值:{this.props.changeState(this.state.val).bind(this)}</p>
</div>
)
}
}
onClick
而且react会把事件代理,你访问时需要在方法中e.event;例如阻止默认事件e.preventDefault()
<div onClick={(e)=>{this.setState({word:e})}}>
{/* 这两种都可以 */}
<div onClick={function(e){this.setState({word:e})}}.bind(this)>
React并没有vue的v-for和v-if等指令;所以判断就是考js来完成;
React的列表渲染就是你请求回来的数组;这里建议通过map方法来完成;也可以根据需求去选择其他方法
这里是js循环方法的使用,可以看看
组件被载入之前
;这里调用this.state不会引起组件重新渲染【这里的内容可以提到constructor中,所以很少使用】组件载入完成
组件是否要被更新
使用布尔值来控制是否需要继续更新;nextProps 下一个props;nextState 指下一个state ; 我们可以用这个组件优化react;使其避免不必要的重复渲染
当组件接受到新的props时触发
;这个组件用于比较state中的值和nextprops是否一样,用不用重新赋值。组件更新前
;这里render函数还未重新渲染组件更新完成
prevProps和prevState指组件更新前的props和state组件卸载前
可以在这里清空定时器,清除挂载后手动创建的DOM,避免内存泄漏React请求与vue大致一样,用axios请求就好啦;
axios中文网很细致,点击看看
父组件在子组件中传入的三个div,这三个div会默认通过props传到子组件中,然后我们在子组件中控制children的渲染即可
cnpm install react-router-dom --save
import {BrowserRouter as Router,Route,Link} from "react-router-dom";
<Router basename='/acs'> //basename设置此路由跟路径
// link to传放置路由路径,也可以传一个对象
<Link to={{path:'/main',seach:'?id=112'hash:'898i',state:{code:1}}}></Link>
{/* */}
// path:要跳转路径 ;exact精确模式,component:跳转的组件
<Router path='/main' exact component={Main}>
</Router>
// 之后接值需要在main组件的props
function Main(props){
return(
console.log(props.mactch) // 在macth中
)
}
<Link to='main/123' >main</Link>
<Route path='main/:id' component={Main}></Route>
function Main(props){
return(
console.log(props.mactch.params) // 在macth的params中
)
}
import {BrowserRouter as Router,Route,Link,Switch,Redirect} from "react-router-dom";
<Redirect to='/mian'></Redirect> //路由重定向
<Router>
<Switch>
<Route path='/abc' exact component={Abc} ></Route>
<Route path='/abc' exact component={Abc} ></Route>
</Switch>
</Router>
// 如果没有switch, 即使有exact严格模式两个路由也都会执行,
// switch就是只执行一个路由
this.props.history.push('/',{id:'11'})
// 跳转到某个路由()中可以传参数;这种方式是在历史中新添加一个页面this.props.history.replace('/',{id:'11'})
// 用 /替换当前页面;这种方式不会添加新页面;this.props.history.go(1)
// 前进一个页面this.props.history.go(-1)
// 后退一个页面cnpm install redux --save
action的type是必须值
// createStore是Redux的一个方法,Redux.createStore也可以
import {createStore} from 'redux'
// 创建一个store ;reducer是一个函数用来改变数据
const store = createStore(reducer)
// state设置默认值,actipn是传入参数
const reducer=functiom(state={num:1},action){
...
return state // 返回新的state
}
store.dispatch({type:'add'}) //改变reducer函数的方法
store.getState() // 获取store中state数据
store.subscribe(()=>{ // store中state数据改变时调用的函数
})
阮一峰的网络日志 ,看看大神会有更多收获
cnpm install react-redux --save
import {createStore} from 'rudux'
import {Povider,connect} from 'react-redux'
// react-redux可以使用组件props和store进行传递数据
class Mycont extends React.component{
rander(){
const value=this.props.value;
const onClickevent=this.props.onClickevent
}
}
const store=creatStore(reducer) //创建store
// ActionObj单独放需要改变state的方法 的对象
let ActionObj={
change:function(state){
state= state.toString()
return state
}
....其他方法
}
// 创建reducer函数
const reducer=function(state={},action){
state= ActionObj[action.type](action.另一个参数)
....其他操作
return {...state} // 结构方法
}
// 创建链接state和props函数;**state行参是必须**
function mapStateToProps(state){
return {
value:state.num
}
}
// 创建dispatch方法和props;**dispatch行参是必须**
function mapDispatchToProps(dispatch){
return {
onClickevent:()=>{dispatch()}
}
}
// connect作用就是将两个方法映射在需要的组件中
const App=connect(
mapStateToProps,
mapDispatchToProps,
)(Mycont) //(Mycont)是需要的组件
// Povider 组件自动将store的state和组件进行关联
ReactDom.render(
<Povider store={store}>
<App /> {/* */}
</Provider>,
document.querySelector('#root')
)
Ant ui官网