好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

React笔记

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添加到数组的最前面 
     }    
}
 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

查看更多关于React笔记的详细内容...

  阅读:36次