React JS Tutorials for Beginners - 1 - Getting Started https: // HdhCmsTestyoutube测试数据/watch?v=-AbaV3nrw6E&list=PL6gx4Cwl9DGBuKtLgPR_zWYnrwv-JllpA
Downloads: https: // facebook.github.io/react/downloads.html
Sample code:https: // github测试数据/buckyroberts/React-Boilerplate
browser.min.js: Convert jsx into javascript, jsx转换网站https: // babeljs.io/repl/
React JS Tutorials for Beginners - 2 - Simple Demo https: // HdhCmsTestyoutube测试数据/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测试数据ments;
arr.push(text); // push,把元素加入数组
this .setState({comments:arr});
},
removeComment: function (i){
var arr= this .state测试数据ments;
arr.splice(i, 1); // 从第i个开始,去掉1个元素.返回新的数组.
this .setState({comments:arr});
},
updateCommand: function (newText,i){
var arr= this .state测试数据ments;
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测试数据ments.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: // HdhCmsTestyoutube测试数据/watch?v=1iAG6h9ff5s&index=6&list=PLoYCgNOIyGABj2GQSlDRjgvXtqfDxKm5b
Bootstrap模版: startbootstrap测试数据
安装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测试数据/somedataendpoint").then((data)=> {
console.log( "got the data!" ,data);
});
Redux核心概念有三个:actions,store,reducers.
Immutable JS - Redux Tutorial #2 - React.js Tutorial https: // HdhCmsTestyoutube测试数据/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: // HdhCmsTestyoutube测试数据/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: // HdhCmsTestyoutube测试数据/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: // HdhCmsTestyoutube测试数据/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: // HdhCmsTestyoutube测试数据/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: // HdhCmsTestyoutube测试数据/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: // HdhCmsTestyoutube测试数据/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: // HdhCmsTestyoutube测试数据/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: // HdhCmsTestyoutube测试数据/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: // HdhCmsTestyoutube测试数据/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: // HdhCmsTestyoutube测试数据/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: // HdhCmsTestyoutube测试数据/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测试数据/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测试数据/ajax/libs/babel-core/5.8.25/browser.min.js"></script>
<script type="text/babel">
...
</script>
Learning React.js [ 3] - Adding Properties https: // HdhCmsTestyoutube测试数据/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: // HdhCmsTestyoutube测试数据/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: // HdhCmsTestyoutube测试数据/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: // HdhCmsTestyoutube测试数据/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: // HdhCmsTestyoutube测试数据/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: // HdhCmsTestyoutube测试数据/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: // HdhCmsTestyoutube测试数据/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: // HdhCmsTestyoutube测试数据/watch?v=QY7Ibl37_08&list=PLillGF-RfqbbKWfm3Y_RF57dNGsHnkYqO&index=10
页面代码中添加: <script src="https://cdn.firebase测试数据/js/client/1.0.17/firebase.js"></script>
componentWillMount: function (){
this .firebaseRef = new Firebase('https://todolistdev1.firebaseio测试数据/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: // HdhCmsTestyoutube测试数据/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: // HdhCmsTestyoutube测试数据/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: // HdhCmsTestyoutube测试数据/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: // HdhCmsTestyoutube测试数据/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测试数据 选择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: // HdhCmsTestyoutube测试数据/watch?v=Ly-9VTXJlnA
使用react-chartjs-2: https: // github测试数据/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: // HdhCmsTestyoutube测试数据/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: // HdhCmsTestyoutube测试数据/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测试数据/react-router/, 要使用左侧的<Switch>,<BrowserRouter>
npm install --save react-router react-router- dom
创建router: src > components > Main.js, 把Main放在App component中:<Main />
样式: materializecss测试数据 /
Full Stack React & LoopBack [3] - Fetching & Displaying Meetups https: // HdhCmsTestyoutube测试数据/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: // HdhCmsTestyoutube测试数据/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: // HdhCmsTestyoutube测试数据/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: // HdhCmsTestyoutube测试数据/watch?v=yU5DYccb77A
返回text的API: hipsterjesus测试数据
npm install axios --save // axios网址 https://github测试数据/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: // HdhCmsTestyoutube测试数据/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: // HdhCmsTestyoutube测试数据/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: // HdhCmsTestyoutube测试数据/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: // HdhCmsTestyoutube测试数据/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测试数据/reactjs/react-router-tutorial/tree/master/lessons
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ReactJS / Redux Tutorial - #3 Using Redux https: // HdhCmsTestyoutube测试数据/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: // HdhCmsTestyoutube测试数据/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: // HdhCmsTestyoutube测试数据/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: // HdhCmsTestyoutube测试数据/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: // HdhCmsTestyoutube测试数据/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: // HdhCmsTestyoutube测试数据/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: // HdhCmsTestyoutube测试数据/watch?v=YmGm-qwbJdc&index=9&list=PL55RiY5tL51rrC3sh8qLiYHqUV3twEYU_
app文件夹下创建reducers,actions文件夹,创建store.js文件.
ReactJS / Redux Tutorial - #10 Async Actions https: // HdhCmsTestyoutube测试数据/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: // HdhCmsTestyoutube测试数据/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: // HdhCmsTestyoutube测试数据/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测试数据/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测试数据/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://haodehen.cn/did222512