实践出真知
npm init -y
npm i babel-loader babel-preset-env babel-preset-react webpack webpack-cli webpack-dev-server babel-core react react-dom react-router-dom redux react-redux
新增webpack.config.js
const webpack = require('webpack');
const path = require('path');
module.exports = {
devtool:"source-map",
entry: {
list:'./src/list.js'
},
output: {
filename: '[name].js',
path: path.join(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: ["react",'env']
}
}
]
},
devServer:{
contentBase:'./dist'
}
};
package.json
"dev": "webpack-dev-server --open"
配置完成
src:
list.js
const React = require("react");
const ReactDom = require("react-dom");
class List extends React.Component{
constructor(props){
super(props);
}
// 只是对自身的渲染
render(){
return <ul>
<li>111</li>
<li>222</li>
<li>333</li>
<li>444</li>
</ul>
}
}
ReactDom.render(<List></List>,document.body);//List的实例
dist:
index.html
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script type="text/javascript" src="list.js">
</script>
</body>
</html>
可尝试用组件哦-静态组件 props
list
const React = require("react");
const ReactDom = require("react-dom");
import Li from "./Li";
class List extends React.Component{
constructor(props){
super(props);
}
// 只是对自身的渲染
render(){
return <ul>
<Li title={"hello"} content="hello world1"></Li>
<Li title="hh" content="hello world2"></Li>
<Li title="oo" content="hello world3"></Li>
</ul>
}
}
ReactDom.render(<List></List>,document.body);//List的实例
新增Li作为组件
const React = require("react");
const ReactDom = require("react-dom");
import Li from "./Li";
class List extends React.Component{
constructor(props){
super(props);
}
// 只是对自身的渲染
render(){
return <ul>
<Li title={"hello"} content="hello world1"></Li>
<Li title="hh" content="hello world2"></Li>
<Li title="oo" content="hello world3"></Li>
</ul>
}
}
ReactDom.render(<List></List>,document.body);//List的实例
外部数据
list
const React = require("react");
const ReactDom = require("react-dom");
import Li from "./Li";
class List extends React.Component{
constructor(props){
super(props);
}
// 只是对自身的渲染
render(){
const articles = this.props.articles;
const lis = articles.map(article=> <Li title={article.title} content={article.content} />);
return <ul>
{lis}
</ul>
}
}
const articles =[
{title:"hhh1",content:"hh1conten"},
{title:"hhh2",content:"hh2conten"},
{title:"hhh3",content:"hh3conten"},
{title:"hhh4",content:"hh4conten"}
];
ReactDom.render(<List articles={articles}></List>,document.body);//List的实例
Li同上
动态组件 state
list
import React from "react";
import ReactDom from "react-dom";
class Time extends React.Component{
constructor(props){
super(props);
this.state = { num: 0 };
}
render(){
if(this.state.num < this.props.max ){
setTimeout(()=>{
this.setState({num:this.state.num +1});
},1000);
}
return <div>
{ this.state.num }
</div>
}
}
ReactDom.render(<Time max={6} />,document.body);
当调用 setState()时触发渲染
事件处理
onXXX = {this.handle} 由自身方法handle处理
this.handle = this.handle.bind(this)对自身转换,把自身的函数,上下文的对象会失效,通过这种方式绑定。
handle(event){}
event和jquery event基本相同。
import React from "react";
import ReactDom from "react-dom";
class List extends React.Component{
constructor(props){
super(props);
this.state = {anum : 1,bnum: 1};
this.listenerHandle = this.listenerHandle.bind(this);
}
listenerHandle(type){
if(type ==="a"){
this.setState({anum:this.state.anum +1});
}else if(type ==="b"){
this.setState({bnum:this.state.bnum +1});
}
}
render(){
return <ul>
<li> A: {this.state.anum}</li>
<li onClick={()=>this.listenerHandle("a")}>a</li>
<li onClick={function(){this.listenerHandle("a")}.bind(this)}>a</li>
<li> B: {this.state.bnum}</li>
<li onClick={()=>this.listenerHandle("b")}>b</li>
</ul>
// 这个地方不调用,不是this.listenerHandle()
}
}
ReactDom.render(<List/>,document.body);
无参数时
<li onClick={this.listenerHandle}>a</li>
自定义事件
sub.js
import React from "react";
export default class Sub extends React.Component{
constructor(props){
super(props);
this.handle = this.handle.bind(this);
this.state = {num : 0};
}
handle(){
++this.state.num;
// this.setState({num:this.state.num +1});
if(!(this.state.num % 5)){
this.props.onFive(this.state.num);
}
}
render(){
return <button onClick={this.handle}>click me </button>
}
}
list
import React from "react";
import ReactDom from "react-dom";
import Sub from "./sub";
class Panel extends React.Component{
constructor(props){
super(props);
this.state = {num : 0};
this.handle = this.handle.bind(this);
}
handle(num){
this.setState({num});
}
render(){
return <div>
<h1>{ this.state.num }</h1>
<Sub onFive={this.handle}/>
</div>
}
}
ReactDom.render(<Panel/>,document.body);
使用key属性 遍历
const React = require("react");
const ReactDom = require("react-dom");
const uuid = require("uuid").v1;
class List extends React.Component{
constructor(props){
super(props);
this.state = {}
this.state.list = props.list.map(function(str){
return {str,key:uuid()}
});
}
del(key){
let delIndex;
//for(;;)效率更高
this.state.list.forEach((item,index)=>{
if(item.key === key){
delIndex = index;
}
})
this.state.list.splice(delIndex,1);
this.setState({list:this.state.list});
//this.forceUpdate() 不管数据是否更改,强制render()
}
// 只是对自身的渲染
render(){
const lis = this.state.list.map(item=><li onClick={()=>this.del(item.key)} key={item.key}> {item.str}</li>)
return <ul>
{lis}
</ul>
}
}
const list = ["aaa","bbb","ccc","ddd"];
ReactDom.render(<List list={list}></List>,document.body);
使用classname style
import React from "react";
import ReactDom from "react-dom";
class MyForm extends React.Component{
constructor(props){
super(props);
this.state ={body:"default",num:0}
this.add = this.add.bind(this);
}
add(){
this.setState({num:this.state.num +1});
}
closeSubmit(event){
event.preventDefault();
}
render(){
let style = {backgroundColor:"#eeeeee"};
return <form onSubmit={this.closeSubmit}>
<textarea value={this.state.body + this.state.num} style={style}></textarea>
<button className={"testclass"} onClick={this.add}>click</button>
</form>
}
}
ReactDom.render(<MyForm/>,document.body);
实例
import React from "react";
import ReactDom from "react-dom";
class Tabs extends React.Component{
constructor(props = { list : [] }){
super(props);
// this.state ={}
// this.state.list = this.props.list;
this.state = {
list : this.props.list,
currentName: null
}
}
select(name){
this.setState({currentName: name}); // render
}
render(){
let as = [];
let div;
this.state.list.forEach(tab =>{
as.push(<a className={this.state.currentName === tab.name ? "active" : ""} key={tab.name} onClick={()=>this.select(tab.name)}> {tab.name} </a>);
// divs.push(<div key={tab.name}>{tab.body}</div>)
if(this.state.currentName === tab.name){
div = <div>{tab.body}</div>
}
});
return <div className="tabs">
<nav>
{as}
</nav>
{ div }
</div>
}
}
const list = [
{name:"A", body:"aaaa"},
{name:"B", body:"bbbb"},
{name:"C", body:"cccc"},
]
ReactDom.render(<Tabs list={list}/>,document.body);
组件
例子
import React from "react";
import ReactDom from "react-dom";
export default class ListPanel extends React.Component{
constructor(props = {list:[]}){
super(props);
// list [ {id , name , selected } ]
// this.state = {};
// this.state.list = this.props.list;
}
// select(id){
// console.log(id);
// const list = this.state.list;
// for(let i=0;i< this.state.list.length ; i++){
// if(list[i].id === id){
// let item = list[i];
// item.selected = !item.selected;
// }
// }
// this.setState({list});
// if(this.props.onUpdate){
// this.props.onUpdate(this.state.list);
// }
// }
// add(item){
// const list = this.state.list;
// list.push(item);
// this.setState({list});
// }
// del(id){
// const list = this.state.list;
// let index = null;
// for(let i=0;i<list.length;i++){
// let item = list[i];
// if(item.id === id){
// index = i;
// break;
// }
// }
// if(index !== null){
// list.splice(index,1);
// this.setState({list});
// }
// }
render(){
const lis = this.props.list.map(item=><li className={item.selected ? "selected" :""} key={item.id} onClick={()=>this.props.onSelect(item.id)}>{ item.name }</li>)
return <ul>
{lis}
</ul>
}
}
import React from "react";
import ReactDom from "react-dom";
import ListPanel from "./ListPanel";
const uuid = require("uuid").v1;
const list = [
{name:"aaaaa" ,id:uuid()},
{name:"bbbbb" ,id:uuid()},
{name:"ccccc" ,id:uuid()},
{name:"ddddd" ,id:uuid()}
];
class LRApp extends React.Component{
constructor(props = {list:[]}){
super(props);
this.state = {
leftList:this.props.list,
rightList: []
};
this.selectLeft = this.selectLeft.bind(this);
this.selectRight = this.selectRight.bind(this);
this.moveLeft = this.moveLeft.bind(this);
this.moveRight = this.moveRight.bind(this);
}
selectLeft(id){
const list = this.state.leftList;
for(let i=0;i< list.length ; i++){
if(list[i].id === id){
let item = list[i];
item.selected = !item.selected;
}
}
this.setState({leftList : list});
}
selectRight(id){
const list = this.state.rightList;
for(let i=0;i< list.length ; i++){
if(list[i].id === id){
let item = list[i];
item.selected = !item.selected;
}
}
this.setState({rightList : list});
}
moveRight(){
let selectedItems = [];
this.state.leftList.forEach(item=>{
if(item.selected){
selectedItems.push(item);
}
});
const leftList = this.state.leftList;
const rightList = this.state.rightList;
for(let i=0;i<selectedItems.length;i++){
rightList.push(selectedItems[i]); // add
this.delLeftItem(selectedItems[i].id);
}
this.forceUpdate(); // render()
}
moveLeft(){
let selectedItems = [];
this.state.rightList.forEach(item=>{
if(item.selected){
selectedItems.push(item);
}
});
const leftList = this.state.leftList;
const rightList = this.state.rightList;
for(let i=0;i<selectedItems.length;i++){
leftList.push(selectedItems[i]); // add
this.delRightItem(selectedItems[i].id);
}
this.forceUpdate(); // render()
}
delRightItem(id){
const list = this.state.rightList;
let index = null;
for(let i=0;i<list.length;i++){
let item = list[i];
if(item.id === id){
index = i;
break;
}
}
if(index !== null){
list.splice(index,1);
// this.setState({list});
}
}
delLeftItem(id){
const list = this.state.leftList;
let index = null;
for(let i=0;i<list.length;i++){
let item = list[i];
if(item.id === id){
index = i;
break;
}
}
if(index !== null){
list.splice(index,1);
// this.setState({list});
}
}
render(){
return <div>
<div style={{float:"left"}}>
<ListPanel list={this.state.leftList} onSelect={ this.selectLeft }/>
</div>
<div style={ {float:"left"} }>
<button onClick={this.moveLeft}> <= </button>
<button onClick={this.moveRight}> => </button>
</div>
<div style={ {float:"left"} }>
<ListPanel list={this.state.rightList} onSelect = {this.selectRight} />
</div>
</div>
}
}
ReactDom.render(
<LRApp list={list}/>
,document.body);