React JS Tutorials for Beginners - 1 - Getting Started https: // www.youtube.com/watch?v=-AbaV3nrw6E&list=PL6gx4Cwl9DGBuKtLgPR_zWYnrwv-JllpA Downloads: https: // facebook.github.io/react/downloads.html Sample code:https: // github.com/buckyroberts/React-Boilerplate browser.min.js: Convert jsx into javascript, jsx转换网站https: // babeljs.io/repl/ React JS Tutorials for Beginners - 2 - Simple Demo https: // www.youtube.com/watch?v=2NLgQMs2hOw&index=2&list=PL6gx4Cwl9DGBuKtLgPR_zWYnrwv-JllpA Sample Demo: <div ></div> <script type="text/babel"> // 注意是txt/babel ReactDOM.render(<h1>Hello World</h1>,document.getElementById('example')); //将Html代码填充到指定的div中 </script> 3 . Components: <div ></div> <script type="text/babel"> var Bacon=React.createClass({ // createClass创建component render: function (){ return (<div> // 只能返回一个父元素 <h2>This is a simple component!</h2> <p>This is a simple component!</p> </div> ); } }); ReactDOM.render( <Bacon />,document.getElementById('example')); // ReactDOM.render(<div><Bacon /><Bacon /><Bacon /></div>,document.getElementById('example')); //呈现多个Component </script> 4 . Props (Property) <div ></div> <script type="text/babel"> var Movie=React.createClass({ // createClass创建component render: function (){ return (<div> <h1>{ this .props.title}</h1> <h2>{ this .props.genre}</h2> </div> ); } }); // ReactDOM.render(<Movie />,document.getElementById('app')); ReactDOM.render(<div> <Movie title="Avatar" genre="action" /> <Movie title="The Notebook" genre="romance" /> <Movie title="Captain America" genre="action" /> </div>,document.getElementById('app')); //呈现多个Component </script> 5 . Event Handling <div ></div> <script type="text/babel"> var Comment=React.createClass({ // createClass创建component edit: function (){ alert( "edit" ); }, remove: function (){ alert( "remove" ); }, render: function (){ return (<div className="commentContainer"> // 注意是className <div className="commentText">{ this .props.children}</div> //this.props.children显示下面<Comment></Comment> 之间的内容 <button onClick={ this .edit} className="button-primary">Edit</button> //事件处理onClick={this.edit} <button onClick={ this .remove} className="button-danger">Remove</button> </div> ); } }); ReactDOM.render( <div className="board"> <Comment>Hey my name is Steve</Comment> <Comment>Jack</Comment> <Comment>Amy</Comment> </div>,document.getElementById('container')); </script> 6 . State <div ></div> <script type="text/babel"> var Checkbox=React.createClass({ // createClass创建component getInitialState: function (){ // getInitialState设置初始状态 return {checked:ture} }, handleChecked: function (){ this .setState({checked: ! this .state.checked}); // setState设置状态 }, render: function (){ var msg; if ( this .state.checked){ msg ="checked" } else { msg ="unchecked" } return (<div> <input type='checkbox' onChange={ this .handleChecked} defaultChecked={ this .state.checked} /> / // /defaultChecked绑定初始状态 <h2>Checkbox is {msg}</h2> </div>); } }); ReactDOM.render( <Checkbox />,document.getElementById('container')); </script> 7 . Adding State to Components <div ></div> <script type="text/babel"> var Comment=React.createClass({ // createClass创建component getInitialState: function (){ return {editing: false } // 编辑状态为false }, edit: function (){ this .setState({editing: true }); // 设置编辑状态为true }, remove: function (){ alert( "remove" ); }, save: function (){ var val= this .refs.newText.value; // 用ref来获取输入框中的值 this .setState({editing: false }); }, renderNormal: function (){ return (<div className="commentContainer"> <div className="commentText">{ this .props.children}</div> <button onClick={ this .edit} className="button-primary">Edit</button> <button onClick={ this .remove} className="button-danger">Remove</button> </div> ); }, renderForm: function (){ return (<div className="commentContainer"> <textare ref="newText" defaultValue={ this .props.children}></textare> //注意defaultValue, 如果给id会导致很多重名,用ref来获取输入框中的值 <button onClick={ this .save} className="button-success">Save</button> </div> ); }, render: function (){ if ( this .state.editing){ return this .renderForm(); } else { return this .renderNormal(); } } }); ReactDOM.render( <div className="board"> <Comment>Hey my name is Steve</Comment> <Comment>Jack</Comment> <Comment>Amy</Comment> </div>,document.getElementById('container')); </script> 8 . Multiple Child Components (在一个容器内排序多个Components) <div ></div> <script type="text/babel"> var Comment= React.createClass({ getInitialState: function (){ return {editing: false } // 编辑状态为false }, edit: function (){ this .setState({editing: true }); // 设置编辑状态为true }, remove: function (){ this .props.deleteFromBoard( this .props.index); // 调用外层属性deleteFromBoard } save: function (){ var val= this .refs.newText.value; // 用ref来获取输入框中的值 this .props.updateCommentText(val, this .props.index); // 调用外层属性updateCommentText this .setState({editing: false }); }, renderNormal: function (){ return (<div className="commentContainer"> <div className="commentText">{ this .props.children}</div> <button onClick={ this .edit} className="button-primary">Edit</button> <button onClick={ this .remove} className="button-danger">Remove</button> </div> ); }, renderForm: function (){ return (<div className="commentContainer"> <textare ref="newText" defaultValue={ this .props.children}></textare> //注意defaultValue, 如果给id会导致很多重名,用ref来获取输入框中的值 <button onClick={ this .save} className="button-success">Save</button> </div> ); }, render: function (){ if ( this .state.editing){ return this .renderForm(); } else { return this .renderNormal(); } } }); var Board=React.createClass({ // Comment是组件,组件可以有很多个.Board是组件外面的容器用于管理里面的多个组件. getInitialState: function (){ return { comments:[ 'aaaaaa' , 'bbbbbb' , 'cccccc' ] } }, add: function (text){ var arr= this .state.comments; arr.push(text); // push,把元素加入数组 this .setState({comments:arr}); }, removeComment: function (i){ var arr= this .state.comments; arr.splice(i, 1); // 从第i个开始,去掉1个元素.返回新的数组. this .setState({comments:arr}); }, updateCommand: function (newText,i){ var arr= this .state.comments; arr[i] =newText; // 将新值赋值给数组中指定的元素 this .setState({comments:arr}); // 更新数组,将新数组arr更新到comments中 } eachComment: function (text,i){ return ( <Comment key={i} index={i} updateCommentText={ this .updateComment} deleteFromBoard={ this .removeComment}> // 注意关键字 key和index, 以及自定义属性updateCommentText,deleteFromBoard {text} </Comment> ); }, render: function (){ return ( <div> <button onClick={ this .add.bind{ null ,'some default text'}} className="button-info Create">Add New</button> //注意写法onClick={this.add.bind{null,'some default text'}} <div className="board"> { this .state.comments.map( this .eachComment) // map相当于for循环 } </div> </div> ); }; }); ReactDOM.render( <Board />,document.getElementById('container')); </script> --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- constructor(){ super(); this .state={name: "Will" }; } this .setState({name:"Bob" }); changeTitle ={ this .changeTitle.bind( this )} // changeTitle方法在当前js文件中需要用.bind(this) REACT JS TUTORIAL # 6 - React Router & Intro to Single Page Apps with React JS https: // www.youtube.com/watch?v=1iAG6h9ff5s&index=6&list=PLoYCgNOIyGABj2GQSlDRjgvXtqfDxKm5b Bootstrap模版: startbootstrap.com 安装react router的命令: npm install -S react- router Store类似于Angularjs中的Service. componentWillMount(){ // Component的构造函数 TodoStore.on("change", this .getTodos); } componentWillUnmount(){ // 必须卸载这个方法,不然会导致内存泄露. TodoStore.removeListener("change", this .getTodos); } npm install - S flux Actions -> Dispatcher -> Stores -> Components -> Actions. import * as TodoAcions from "action/TodoAcions"; // 表示TodoActions中的所有方法. Ajax: axios( "http://someurl.com/somedataendpoint").then((data)=> { console.log( "got the data!" ,data); }); Redux核心概念有三个:actions,store,reducers. Immutable JS - Redux Tutorial #2 - React.js Tutorial https: // www.youtube.com/watch?v=9M-r8p9ey8U&list=PLoYCgNOIyGABj2GQSlDRjgvXtqfDxKm5b&index=16 var a={name:"Will", things:[0,1,2 ]} var b=Object.assign({},a,{name:"Fred" }) b.things =a.things.concat(3 ) state = {...state,age:action.payload} Redux Middleware Tutorial - Redux Tutorial #5 https: // www.youtube.com/watch?v=DJ8fR0mZM44&list=PLoYCgNOIyGABj2GQSlDRjgvXtqfDxKm5b&index=19 中间件: import {applyMiddleware,createStore} from "redux" ; const logger =(store)=>(next)=>(action)=> { console.log( "action fired" ,action); next(action); } const store =createStore(reducer,1 ,middleware) Connecting React & Redux - Redux Tutorial #7 https: // www.youtube.com/watch?v=nrg7zhgJd4w&index=21&list=PLoYCgNOIyGABj2GQSlDRjgvXtqfDxKm5b import {connect} from "react-redux" @connect((store) => { return { user:store.user.user, userFetched:store.user.fetched, tweets:store.tweets.tweets, }; }) ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ReactJS / Redux Tutorial - #1 Introduction https: // www.youtube.com/watch?v=qrsle5quS7A&list=PL55RiY5tL51rrC3sh8qLiYHqUV3twEYU_ npm install redux -save // 安装redux js中的对象: const initialState = { result: 1 , lastValues:[] } state = { ...state, // ES6语法,包括state对象的所有属性 result: state.result + action.payload, lastValues: [...state.lastValues,action.payload] } ReactJS / Redux Tutorial - #5 Multiple Reducers https: // www.youtube.com/watch?v=BVvBa18o8Es&list=PL55RiY5tL51rrC3sh8qLiYHqUV3twEYU_&index=5 import {createStore, combineReducers} from "redux" const store = createStore(combineReducers({mathReducer,userReducer})); ReactJS / Redux Tutorial - #6 Redux Middleware https: // www.youtube.com/watch?v=AgO7YcJeBh4&index=6&list=PL55RiY5tL51rrC3sh8qLiYHqUV3twEYU_ import {createStore, combineReducers, applyMiddleware} from "redux" const myLogger = (store) => (next) => (action) => { console.log( "Logged Action" ,action); next(action); } const store = createStore(combineReducers({mathReducer,userReducer}), {}, applyMiddleware(myLogger)); npm install redux -logger -- save import logger from "redux-logger" ; const store = createStore(combineReducers({mathReducer,userReducer}), {}, applyMiddleware(logger())); ReactJS / Redux Tutorial - #7 Connect ReactJS and Redux https: // www.youtube.com/watch?v=tfuZ7uZmVyg&list=PL55RiY5tL51rrC3sh8qLiYHqUV3twEYU_&index=7 npm install react-redux -- save import {connect} from "react-redux" ; import {Provider} from "react-redux" ; <Provider store={store}> <App/> </Provider> const mapStateToProps = (state) => { return { user: state.userReducer, math: state.mathReducer } } const mapDispatchToProps = (dispatch) => { return { setName:(name) => { dispatch({ type: "SET_NAME" , payload: name }); } } } export default connect(mapStateToProps,mapDispatchToProps)(app); <Main changeUsername={()=> this .props.setName("Anna")} /> <User username={ this .props.user.name} /> ReactJS / Redux Tutorial - #8 Containers & Components (Smart & Dumb Components) https: // www.youtube.com/watch?v=m2q3Dyr6To4&list=PL55RiY5tL51rrC3sh8qLiYHqUV3twEYU_&index=8 Dumb Components 只是方法不是类, 只需要return html不需要render. Smart Components放在containers文件夹下, Dumb Components放在components下. ReactJS / Redux Tutorial - #9 A better Project Structure https: // www.youtube.com/watch?v=YmGm-qwbJdc&list=PL55RiY5tL51rrC3sh8qLiYHqUV3twEYU_&index=9 app actions, components, containers(app.js), reducers index.js store.js ReactJS / Redux Tutorial - #10 Async Actions https: // www.youtube.com/watch?v=h892pHdLQtM&index=10&list=PL55RiY5tL51rrC3sh8qLiYHqUV3twEYU_ npm install redux-thunk -- save import thunk from "redux-thunk" ; applyMiddleware(logger(),thunk) npm install redux -promise-middleware -- save import promise from "redux-promise-middleware" ; applyMiddleware(logger(),thunk,promise()) return { type: "SET_NAME" , payload: new Promise((resolve, reject) => { setTimeout(() => { resolve(name); }, 2000 ); }) } Reducer.js中 case "SET_NAME_FULFILLED" // 因为这个promise中间件,需要加上_FULFILLED ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Learning React.js [ 1] - An Overview https: // www.youtube.com/watch?v=vYldnghykaU&list=PLillGF-RfqbbKWfm3Y_RF57dNGsHnkYqO when a state is changed, the component is re- rendered and markup will be updated. This makes React very dynamic. Lifecycle Methods: render - Renders a component. The only one that is required. getInitialState - You can set default values for your states. getDefaultProps - Set defaults for properties. componentWillMount - Invoked once on client & server before render. componentDidMount - Invoked after the first render. React Addons: Collection of modules that aid in developing React.js applications Animation Addons 2 Way Data Binding Addons - React Link Testing Addons Learning React.js [ 2] - Your First Component https: // www.youtube.com/watch?v=mDz4HXZHo9g&index=3&list=PLillGF-RfqbbKWfm3Y_RF57dNGsHnkYqO React网址: https: // facebook.github.io/react/docs/getting-started.html <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"> <script src="https://fb.me/react-0.14.7.js"></script> <script src="https://fb.me/react-dom-0.14.7.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.25/browser.min.js"></script> <script type="text/babel"> ... </script> Learning React.js [ 3] - Adding Properties https: // www.youtube.com/watch?v=euSbXxCf88I&index=2&list=PLillGF-RfqbbKWfm3Y_RF57dNGsHnkYqO propTypes:{ title:React.PropTypes.string.isRequired }, getDefaultProps: function (){ return { title: "111" , text: "222" , link: "333" } } Learning React.js [ 4] - Events https: // www.youtube.com/watch?v=CVigtRUxj2I&list=PLillGF-RfqbbKWfm3Y_RF57dNGsHnkYqO&index=4 <a onClick={ this .OnClick.bind( this , 'Hello','Goodbye')}> // 带参数的function onClick: function (msg,msg2){ alert(msg2); // 弹出Goodbye } Learning React.js [ 5] - State and Nesting Components https: // www.youtube.com/watch?v=_o9NTYfbkR0&index=6&list=PLillGF-RfqbbKWfm3Y_RF57dNGsHnkYqO getInitialState: function (){ return { text: 'Hello World' } } <h1>{ this .state.text}</h1> <input type="text" onChange={ this .changeText} value={ this .state.text} /> changeText: function (e){ this .setState({text: e.target.value}); // setState, e.target.value } Learning React.js [ 6] - Mapping Data https: // www.youtube.com/watch?v=499IaPWLHKU&index=5&list=PLillGF-RfqbbKWfm3Y_RF57dNGsHnkYqO React中的循环: <ul className="list-group"> { this .props.todos.map(todo => { return <li className="list-group-item" todo={todo} key={todo.id}>{todo.name}</li> }) } <ul> Learning React.js [ 7] - Adding State Data Through a Form https: // www.youtube.com/watch?v=yOu_PUAOtP0&index=7&list=PLillGF-RfqbbKWfm3Y_RF57dNGsHnkYqO App component: <TodoForm onTodoAdd={ this .handleTodoAdd} /> handleTodoAdd: function (text){ var newTodo= { id: this .state.todos.length + 1 , text: text } this .setState({todos: this .state.todos.concat(newTodo)}); // concat向数组里面添加对象 } TodoForm component: <form onSubmit={ this .onSubmit}> <input type="text" ref="text" onChange={ this .onChange} className="form-control" /> //ref="text" </form> onSubmit: function (e){ // e参数, refs e.preventDefault(); var text = this .refs.text.value.trim(); if (! text){ alert( 'Please enter a todo' ); return ; } this .props.onTodoAdd(text); // 调用传过来的props方法onTodoAdd() this .refs.text.value='' ; } Learning React.js [ 8] - Deleting State Data https: // www.youtube.com/watch?v=AUso8hw2-JQ&index=8&list=PLillGF-RfqbbKWfm3Y_RF57dNGsHnkYqO <TodoList todos={ this .state.todos} deleteTodo={ this .handleTodoDelete} /> //这里的handleTodoDelete不用指定参数 handleTodoDelete: function (todo){ var todos = this .state.todos; for ( var i=0;i<todos.length;i++ ){ if (todos[i].id== todo.id){ todos.splice(i, 1 ); } } this .setState({todos: todos}); } <a onClick={ this .onDelete.bind( this ,todo)} > onDelete(todo){ this .props.deleteTodo(todo); } Learning React.js [ 9] - Updating State Data https: // www.youtube.com/watch?v=WI8Z1RKzhMM&index=9&list=PLillGF-RfqbbKWfm3Y_RF57dNGsHnkYqO <TodoForm {... this .state} onTodoAdd={ this .handleTodoAdd} /> //{...this.state}会把整个state传到控件TodoForm中,TodoForm控件中用{this.props.text}来获得state中的值. < TodoList // todos={this.state.todos} {... this .state} // {...this.state}会把整个state传到该控件中 editTodo={ this .handleTodoEdit} /> handleTodoEdit: function (todo){ this .setState({text:todo.text, isEdit: todo.id}); } <span onClick={ this .editTodo.bind( this ,todo)}> editTodo: function (todo){ this .props.editTodo(todo); } < TodoForm {... this .state} changeText ={ this .handleChangeText} onTodoUpdate ={ this .handleTodoUpdate} /> handleChangeText: function (text){ this .setState({text: text}); } handleTodoUpdate: function (todo){ var todos = this .state.todos; for ( var i=0;i<todos.length;i++ ){ if (todos[i].id== todo.id){ todos.splice(i, 1 ); } } todos.push(todo); this .setState({todos: todos}); } TodoForm 组件中: <input type="text" onChange={ this .onChange}> onChange: function (e){ this .props.changeText(e.target.value); // input没有onChange方法, 没有this.props.changeText的话input中的值输入会没有变化 } onSubmit方法中: if ( this .props.isEdit){ var updateTodo = { id: this .props.isEdit, text:text } this .props.onTodoUpdate(updatedTodo); } else { this .props.onTodoAdd(text); } Learning React.js [ 10] Persisting Data To Firebase https: // www.youtube.com/watch?v=QY7Ibl37_08&list=PLillGF-RfqbbKWfm3Y_RF57dNGsHnkYqO&index=10 页面代码中添加: <script src="https://cdn.firebase.com/js/client/1.0.17/firebase.js"></script> componentWillMount: function (){ this .firebaseRef = new Firebase('https://todolistdev1.firebaseio.com/todos' ); var that = this ; this .firebaseRef.once("value", function (snapshot){ // Get todo list from database var todos = []; snapshot.forEach( function (data){ var todo = { id: data.val().id, text: data.val().text } todos.push(todo); that.setState({todos: todos}); }); }); } Add: this .firebaseRef.push(newTodo); ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- React & Express Starter Pack For Full Stack Development https: // www.youtube.com/watch?v=v0t42xBIYIs 项目模版的使用: git clone https: // ... npm install npm run client - install npm run dev // 会同时启动客户端和服务端,因为使用了模块concurrently. localhost:3000打开客户端, localhost:5000/api/customers打开服务端. 创建项目: mkdir reactexpress cd reactexpress npm init npm i express concurrently npm i nodemon --save- dev package.json文件修改: "scripts" :{ "start":"node server.js" , "server":"nodemon server.js" } touch server.js // 创建文件 code server.js // 用vs code打开文件 npm run server // 启动服务端 打开另外一个命令窗口: npm i -g create-react-app // 安装react的cli create-react-app client // 创建react项目放在client下 打开client>package.json文件添加节点"proxy":"http://localhost:5000" 指定服务端地址. npm start // 启动react客户端 npm run dev同时启动客户端和服务端, 修改server端下面的package.json文件: "scripts" :{ "client-install":"cd client && npm install" , "start":"node server.js" , "server":"nodemon server.js" , "client":"npm start --prefix client" , "dev":"concurrently \"npm run server\" \"npm run client\"" } -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- React JS Crash Course https: // www.youtube.com/watch?v=A71aqufiNtQ 官网: https: // facebook.github.io/rect npm install -g create-react- app create -react-app projectmanager // 创建项目命令 npm start React使用的语法叫JSX. 生成GUID的插件: npm install -- save uuid npm start import uuid from 'uuid' ; uuid.v4(); // 生成GUID 安装jquery: npm install jquery -- save npm start import $ from 'jquery' ; react里面不用name用ref ? <input type="text" ref="title"> if ( this .refs.title.value === '' ) child component: this .props.addProject( this .state.newProject); father component: <AddProject addProject={ this .handleAddProject.bind( this )} /> handleAddProject(project){ console.log(project); } handleDeleteProject(id){ let projects = this .state.projects; let index =projects.findIndex(x=>x.id===id); // findIndex找到要删除元素的序列号 projects.splice(index,1 ); this .setState({projects:projects}); } 类型验证: Projects.propTypes = { projects:React.PropTypes.array, onDelete:React.PropTypes.func } setState有返回函数: this .setState({todos:data}, function (){ console.log( this .state); }); state在构造函数中初始化, 在componentWillMount中赋值. -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- The 2017 React Development Starter Guide https: // www.youtube.com/watch?v=7ojad6QYuqI Add Todo: this .state= { todoTitle: '' } this .handleInputChange= this .handleInputChange.bind( this ); // 放在构造函数里面? handleInputChange(event){ const target = event.target; const target = event.target; const target = event.target; this .setState({ [name]:value }) } handleSubmit(event){ event.preventDefault(); this .props.onAddTodo( this .state); this .setState({ todoTitle: '' }); } <form onSubmit={ this .handleSubmit.bind( this )}> <input type="text" > name="todoTitle" // 可以有name value={ this .state.todoTitle} // 绑定上面的todoTitle onChange={ this .handleInputChange} // 没有这个方法输入不了 /> 父Component中: handleAddTodo(todo){ this .setState({todos:[... this .state.todos, todo]}) } -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Learn Redux - Introduction To State Management With React https: // www.youtube.com/watch?v=SGOFxK-28ns&index=1&list=PL2dKqfImstaSl8Hi6UrovwraEHvK2MNPt Component > Action > Store <> Reducer npm add redux // 在react项目中添加redux package 创建src>actions> index.js One Action Example: export const voteReact = () => { return { type: 'VOTE_REACT' } } src >reducers> index.js reducer example: const initialState = { angular: 0 , react: 0 , vuejs: 0 } export default (state = initialState, action) => { switch (action.type){ case 'VOTE_REACT' : return Object.assign({},state,{ react:state.react + 1 }) default : return state } } 模版样式:https: // bootswatch.com 选择Yeti, 加入public > Index.html 页面样式中. App.js: constructor(props){ super(props); this .store = this .props.store; // props是不是可以理解为parent?表示父控件中有属性store } handleVoteReact = ()=> { this .store.dispatch(voteReact()); // dispatch reducer } <div style={{'textAlign':'center'}}> // 内联样式用双引号 index.js: let store = createStore(myApp); function render(){ ReactDOM.render( <App store={store} />, document.getElementById('root' ) ); } store.subscribe(render); render(); { this .voteAngularInPercent().toFixed(2) + '%'} // 这里的this.voteAngularInPercent()是function -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Using Chart.js With React https: // www.youtube.com/watch?v=Ly-9VTXJlnA 使用react-chartjs-2: https: // github.com/gor181/react-chartjs-2 npm install -g create-react-app // 安装 create-react-app my-app // 创建项目 cd my- app npm start npm install react -chartjs-2 chart.js -- save 默认属性: static defaultProps = { displayTitle: true , dsiplayLegend: true } 使用: this .props.displayTitle <Chart displayTitle= false /> //这里的属性值会覆盖默认定义的属性值 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Full Stack React & LoopBack [1] - Intro & LoopBack Server https: // www.youtube.com/watch?v=Mx-cywTNy8s&list=PLillGF-RfqbZjJBAu0sx_0SCuFdzdx4iY&pbjreload=10 service mongod start // 启动mongodb服务 LoopBack - The Node.js API Framework: https: // loopback.io/ npm install -g loopback- cli lb // 创建项目 node . // 启动服务运行app npm install --save loopback-connector- mongodb lb datasource mongoDS --connector mongoDB // 会自动创建文件生成代码 lb model 按Enter键然后输入model name Full Stack React & LoopBack [2] - React, Routing and UI https: // www.youtube.com/watch?v=idvCKXXFGs4&index=2&list=PLillGF-RfqbZjJBAu0sx_0SCuFdzdx4iY 创建文件夹client_src用于存放React项目, 编译后的文件存放于根目录下的clinet文件夹. 用vs code打开client_src文件夹. create -react-app . // react项目创建于当前目录下 使用指定端口, 修改package.json文件: "start":"set PORT=3001 && react-scripts start" // 添加了set PORT=3001 && google搜索react router v4,打开https: // reacttraining.com/react-router/, 要使用左侧的<Switch>,<BrowserRouter> npm install --save react-router react-router- dom 创建router: src > components > Main.js, 把Main放在App component中:<Main /> 样式: materializecss.com / Full Stack React & LoopBack [3] - Fetching & Displaying Meetups https: // www.youtube.com/watch?v=R3wiX05SJps&index=3&list=PLillGF-RfqbZjJBAu0sx_0SCuFdzdx4iY npm install axios --save // 用于http通信 this .setState({meetups: response.data}, ()=>{ // setState有回调函数 console.log( this .state); }); <Link to={`/meetups/${ this .state.item.id}`}> Home </Link> //``符号内的变量${},EX6语法 获取页面地址栏传过来的参数: let meetupId = this .props.match.params.id; Full Stack React & LoopBack [4] - Add, Edit & Delete Meetups https: // www.youtube.com/watch?v=yN5qKqLDlpM&list=PLillGF-RfqbZjJBAu0sx_0SCuFdzdx4iY&index=4 <input type="text" name="name" ref="name" /> console.log( this .refs.name.value); this .handleInputChange = this .handleInputChange.bind( this ); // 放在构造函数里面 handleInputChange(e){ const target = e.target; const value = e.target.value; const name = e.target.name; this .setState({ [name]:value }); } Edit页面: <input type="text" name="name" ref="name" value={ this .state.name} onChange={ this .handleInputChange}/> //没有onChange的方法就不能修改 Full Stack React & LoopBack [5] - Front & Back End Integration https: // www.youtube.com/watch?v=M_PaFaIf6d8&index=5&list=PLillGF-RfqbZjJBAu0sx_0SCuFdzdx4iY 修改react的package.json文件: "build":"react-scripts build && cp -r build/* client/" // 执行npm run build将编译后的文件放到server端的client文件夹 vs code打开根项目文件夹,修改server > boot > root.js: router.get( '/',server.loopback.status()); 改为router.get('/' ); middleware.json: "files" :{ "loopback#static" :{ "params":"$!client" } } node . // 启动项目 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Build & Deploy A React JS Text Generator App https: // www.youtube.com/watch?v=yU5DYccb77A 返回text的API: hipsterjesus.com npm install axios --save // axios网址 https://github.com/mzabriskie/axios import axios from 'axios' onChange(e){ this .setState({value: e.target.value}, function (){ // e.target.value this .props.onChange( this .state.value); }) } <br /> //jsx语法中必须要有/,不能是<br> npm run build // 编译项目到build文件夹, 里面有个static文件夹 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ReactJS Basics - #2 Setup Workspace with Webpack https: // www.youtube.com/watch?v=uextYhQGP6k&list=PL55RiY5tL51oyA8euSROLjMFZbXaV7skS&index=2 npm init npm install react react -dom -- save npm install webpack webpack -dev-server babel-loader babel-preset-es2015 babel-preset-react babel-preset-stage-2 --save-dev // webpack-dev-server会自动刷新页面 根目录下创建webpack.config.js git init .gitignore: /node_modules /dist /npm-debug.log git add . git commit -m "initial commit, setup finished" git checkout -b 01-setup // 创建分支? react propTypes 说明文档: https: // facebook.github.io/react/docs/reusable-components.html Component内部属性: <Home> <p>This is a paragraph!</p> </Home> { this .props.children} Home.propTypes = { children: React.PropTypes.element.isRequired } <button onClick={() => this .onMakeOlder()} > // 事件的这种写法不需要绑定this ReactJS Basics - #10 Stateless Components https: // www.youtube.com/watch?v=SEkfzqIgvTo&index=11&list=PL55RiY5tL51oyA8euSROLjMFZbXaV7skS export const Header = (props) => { return ( <p>{props.homeLink}</p> ) } console.log( "123",nextProps,nextState) // console.log跟Python里面的Print方法类似 ReactJS Basics - #15 React Router - Route Setup https: // www.youtube.com/watch?v=eofpZPRUnP8&list=PL55RiY5tL51oyA8euSROLjMFZbXaV7skS&index=16 npm install --save react- router import {Router,Route,browserHistory,IndexRoute} from "react-router" ; render(){ return ( <Router history={browserHistory}> <Route path={"/"} component={Root}> <IndexRoute component={Home} /> <Route path={"user/:id"} component={User} /> <Route path={"home"} component={Home} /> </Route> <Route path={"home-single"} component={Home} /> </Router> ); } package.json: "build"最后追加 --history-api- fallback ReactJS Basics - #16 React Router - Navigation & Parameters https: // www.youtube.com/watch?v=5pt_igBTCsI&list=PL55RiY5tL51oyA8euSROLjMFZbXaV7skS&index=17 方法一: import {Link} from "react-router" ; <Link to={"/home"} activeStyle={{color:"red"}}>Home</Link> <Link to={"/user/10"} activeClassName={"active"}>User</Link> 方法二: import {browserHistory} from "react-router" ; onNavigateHome(){ browserHistory.push( "/home" ); } <button onClick={ this .onNavigateHome}>Go Home</button> 带参数: { this .props.params.id} React Router文档: https: // github.com/reactjs/react-router-tutorial/tree/master/lessons -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ReactJS / Redux Tutorial - #3 Using Redux https: // www.youtube.com/watch?v=ZKCYqJu4n3s&list=PL55RiY5tL51rrC3sh8qLiYHqUV3twEYU_&index=3 Start the Webpack Dev Server with npm run build and then visit http: // localhost:8080 npm install redux -- save import {createStore} from "redux" ; const reducer = (state,action) => { switch (action.type){ case "ADD" : state = state + action.payload; break ; case "SUBTRACT" : break ; } return state; }; const store = createStore(reducer,1); // 第二个参数1是初始的state store.subscribe(()=> { console.log( "Store updated!" , store.getState()); }); store.dispatch({ type: "ADD" , payload: 10 }); ReactJS / Redux Tutorial - #4 Working with State and Immutability https: // www.youtube.com/watch?v=7bMTJxvEJiE&index=4&list=PL55RiY5tL51rrC3sh8qLiYHqUV3twEYU_ const initialState = { result: 1 , lastValues:[] } const reducer = (state = initialState,action) => { switch (action.type){ case "ADD" : // state.result += action.payload; state= { ...state, // 获得old state result: state.result + action.payload, // 覆盖原result lastValues: [...state.lastValues, action.payload] // 数组里面用... } break ; case "SUBTRACT" : break ; } return state; }; ReactJS / Redux Tutorial - #5 Multiple Reducers https: // www.youtube.com/watch?v=BVvBa18o8Es&index=5&list=PL55RiY5tL51rrC3sh8qLiYHqUV3twEYU_ import {createStore, combineReducers} from "redux" ; const store = createStore(combineReducers({mathReducer, userReducer})); // createStore不能直接传递多个reducer参数,所以使用combineReducers ReactJS / Redux Tutorial - #6 Redux Middleware https: // www.youtube.com/watch?v=AgO7YcJeBh4&list=PL55RiY5tL51rrC3sh8qLiYHqUV3twEYU_&index=6 import {createStore, combineReducers, applyMiddleware} from "redux"; // applyMiddleware const myLogger = (store) => (next) => (action) => { console.log( "Logged Action: " , action); next(action); } const store = createStore(combineReducers({mathReducer, userReducer}),{}, applyMiddleware(myLogger)); 实用的Middleware: npm install redux -logger -- save import logger from "redux-logger" ; const store = createStore(combineReducers({mathReducer, userReducer}),{}, applyMiddleware(logger())); ReactJS / Redux Tutorial - #7 Connect ReactJS and Redux https: // www.youtube.com/watch?v=tfuZ7uZmVyg&index=7&list=PL55RiY5tL51rrC3sh8qLiYHqUV3twEYU_ npm install react-redux -- save import {Provider} from "react-redux" ; index.js: import App from "./components/App"; // 如果是default component这不需要{}, 例如这里是App而不是{App} render( <Provider store= {store} <App/> </Provider>, window.document.getElementById('app' ); ); App.js: import {connect} from "react-redux" ; <Main changeUsername={()=> this .props.setName("Anna")}/> <User username={ this .props.user.name} /> const mapStateToProps = (state) => { return { user: state.user, // key是属性, 这里的user是属性 math: state.math } } const mapDispatchToProps = (dispatch) => { return { setName:(name) => { dispatch({ type: "SET_NAME" , payload:name }); } } } export default connect(mapStateToProps, mapDispatchToProps)(App); // connect this component to store ReactJS / Redux Tutorial - #8 Containers & Components (Smart & Dumb Components) https: // www.youtube.com/watch?v=m2q3Dyr6To4&index=8&list=PL55RiY5tL51rrC3sh8qLiYHqUV3twEYU_ Smart Component: know state. 放在Containers文件夹下 Dumb Component: unknow state. 放在Components文件夹下. 使用export const Main = (props) => {} ReactJS / Redux Tutorial - #9 A better Project Structure https: // www.youtube.com/watch?v=YmGm-qwbJdc&index=9&list=PL55RiY5tL51rrC3sh8qLiYHqUV3twEYU_ app文件夹下创建reducers,actions文件夹,创建store.js文件. ReactJS / Redux Tutorial - #10 Async Actions https: // www.youtube.com/watch?v=h892pHdLQtM&index=10&list=PL55RiY5tL51rrC3sh8qLiYHqUV3twEYU_ npm install redux-thunk --save // 解决错误Actions must be plain objects. Use custom middleware for async actions. store.js: import thunk from "redux-thunk" ; applyMiddleware(thunk) userActions.js: return { type: "SET_NAME" , payload: new Promise((resolve, reject) => { setTimeout(() => { resolve(name); }, 2000 ); }); } npm install redux -promise-middleware -- save store.js: import promise from "redux-promise-middleware" ; applyMiddleware(promise()) userReducer修改action name to SET_NAME_FULFILLED // 添加后缀_FULFILLED, 使用promise()的时候需要添加. React | Redux 使用文档: redux.js.org/docs/basics/UsageWithReact.html -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ReactJS从入门到实战 11 11 表单元素 https: // www.youtube.com/watch?v=hJxRcG1APbQ&t=653s&index=5&list=WL var styles={ // styles是对象,定义在组件外面 inputText:{ width: 100 , fontSize: 24 // 这里是fontSize而不是font-size } } getInitialState: function (){ return { input: 'default' } }, handleTextChange: function (evt){ this .setState({'input' : evt.target.value}); } <input type='text' style={styles.inputText} value={ this .state.input} onChange={ this .handleTextChange} defaultValue={ this .state.input}/> <textarea style={styles.inputText} onChange={ this .handleTextChange} defaultValue={ this .state.input} /> ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- Redux Crash Course With React https: // www.youtube.com/watch?v=93p3LxR9xfM VS Code插件: ES7 React/Redux/GraphQL/React-Native snippets npm start // 启动react dev server,打开localhost:3000 react component code snippet: 'rcc' . 'rfc' code snippet for function . 页面上有多个输入框: <input type="text" name="title" onChange={ this .onChange} value={ this .state.title}/> constructor中: this .onChange = this .onChange.bind( this ); constructor外render外: onChange(e){ this .setState({[e.target.name]: e.target.value}); } Add Post: // 新增 <form onSubmit={ this .OnSubmit.bind( this )}> OnSubmit(e){ e.preventDefault(); const post = { title: this .state.title, body: this .state.body } fetch( 'https://jsonplaceholder.typicode.com/posts' ,{ method: 'POST' , headers:{ 'content-type':'application/json' }, body:JSON.stringify(post) }) .then(res => res.json()) .then(data => console.log(data)); } 安装Redux相关插件: npm i redux react -redux redux- thunk App.js导入Provider 和 store: import {Provider} from 'react-redux' ; import store from './store'; // 创建单独的store.js文件 内容包裹在<Provider> 里面: render(){ return ( <Provider store={store}> ... </Provider> ); } 错误 'react-scripts' is not recognized as an internal or external command. 解决方案:npm install redux官方文档地址: https: // github.com/reactjs/redux/tree/master/docs/api store.js: import {createStore,applyMiddleware} from 'redux' ; import thunk from 'redux-thunk' ; import rootReducer from './reducers' ; ... 创建rootReducer, reducers /index.js: import {combineReducers} from 'redux' ; import postReducer from './postReducer' ; export default combineReducers({ posts: postReducer }); export function fetchPosts(){ return function (dispatch){ ... } } 简化后的写法是: export const fetchPosts =()=>dispatch=> {...} 组件Posts.js中: import {connect} from 'react-redux'; // connect the store to the component componentWillMount(){ this .props.fetchPosts(); // props下的action } const mapStateToProps = state => ({ posts: state.posts.items // 使用的时候用this.props.posts }); export default connect(mapStateToProps,{fetchPosts})(Posts); // 如果没有mapStateToProps,则为null import PropTypes from 'prop-types' ; Posts.propTypes = { fetchPosts:PropTypes.func.isRequired, posts:PropTypes.array.isRequired } 谷歌Redux插件: Google搜索chrome extension redux 点击 Redux DevTools - Chrome Web Store 要使用以上插件,修改store.js: import {createStore, applyMiddleware, compose} from 'redux' ; const store = createStore( rootReducer, initialState, compose( applyMiddleware(...middleware), window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__() ) ); Redux里面的state是application级别的,不是某个Component的state. dispatch里面包括type和payload(要传递的值). componentWillReceiveProps(nextProps){ // when it receives property from state if (nextProps.newPost){ this .props.posts.unshift(nextProps.newPost); // push会添加到数组的最后一位,unshift添加到数组的最前面 } } ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://www.haodehen.cn/did222512