React项目实践(一)之项目创建

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React项目实践(一)之项目创建相关的知识,希望对你有一定的参考价值。

参考技术A 创建项目

生成目录结构

项目创建完成,运行项目

1,新创建工程,第一次引入pod库时。
2,修改了Podfile文件,添加或删除了所依赖的pod库时。
3,团队中新人拉取工程后获取pod库时。
4,团队中,不同开发者要同步对pod库的依赖时。

运行后的项目

1、将 TypeScript 以及 React Native 和 Jest 的依赖添加到您的项目中。

2、添加一个 TypeScript 配置文件。 在项目的根目录中创建一个tsconfig.json:

3、创建一个jest.config.js文件来配置 Jest 以使用 TypeScript:

4、将 javascript 文件重命名为* .tsx

要将自定义路径别名与TypeScript一起使用,您需要设置路径别名以同时在Babel和TypeScript中使用。
因为react-native仅仅使用了typescript的静态类型检查,而实际上使用的是babel的编译器,所以需要在两个地方配置。

2、babel.config.js

4.重启项目

React 实践项目

React在Github上已经有接近70000的 star 数了,是目前最热门的前端框架。而我学习React也有一段时间了,现在就开始用 React+Redux 进行实战!

React 实践项目 (一)

本次实践代码

部署好的网址

上回说到用React写了一个带Header的首页,我们这次实践就使用Redux进行状态管理

Rudex

应用中所有的 state 都以一个对象树的形式储存在一个单一的 store 中。
惟一改变 state 的办法是触发 action,一个描述发生什么的对象。
为了描述 action 如何改变 state 树,你需要编写 reducers。

我们接下来开始开始进行登陆与注册的状态管理

首先在 src 目录下创建 redux 文件夹,目录如下

digag
├── README.md
├── node_modules
├── package.json
├── .gitignore
├── public
│   └── favicon.ico
│   └── index.html
│   └── manifest.json
└── src
    └── components
        └── Index
            └── Header.js
            └── LoginDialog.js
            └── RegisterDialog.js
    └── containers
        └── App
            └── App.js
            └── App.css
    └── redux
        └── action
            └── users.js
        └── reducer
            └── auth.js
            └── users.js
        └── sagas
            └── api.js
            └── sagas.js
            └── selectors.js.js
            └── users.js
        └── store
            └── store.js
    └── App.test.js
    └── index.css
    └── index.js
    └── logo.svg
    └── registerServiceWorker.js

代码可从此获取

记得在 package.json 中更新依赖

接下来我会开始解释关键代码

  • action
    action/users.js
/*
 * action 类型
 */
export const REGISTER_USER = ‘REGISTER_USER‘;
// 省略其他action 类型

/*
 * action 创建函数
 */
export const registerAction = (newUser) => {
  return{
    type:REGISTER_USER,
    data: newUser,
  }
};
// 省略其他 action 创建函数
  • reducer
    reducer/users.js
//Immutable Data 就是一旦创建,就不能再被更改的数据。
//对 Immutable 对象的任何修改或添加删除操作都会返回一个新的 Immutable 对象。
import Immutable from ‘immutable‘;
//从 action 导入需要的 action 类型
import {REGISTER_USER, REGISTER_USER_SUCCESS, REGISTER_USER_FAILURE} from ‘../action/users‘;

// 初始化状态
const initialState = Immutable.fromJS({
  newUser: null,
  error: null,
  saveSuccess: false,
});

//  reducer 就是一个纯函数,接收旧的 state 和 action,返回新的 state。
export const users = (state = initialState, action = {}) => {
  switch (action.type) { // 判断 action 类型
    case REGISTER_USER:  
      return state.merge({   // 更新状态
        ‘newUser‘: action.data,
        ‘saveSuccess‘: false,
        ‘error‘: null,
      });
    case REGISTER_USER_SUCCESS:
      return state.set(‘saveSuccess‘, action.data);
    case REGISTER_USER_FAILURE:
      return state.set(‘error‘, action.data);
    default:
      return state
  }
};
  • store
    store/store.js
import {createStore, combineReducers, applyMiddleware } from ‘redux‘;
import createSagaMiddleware from ‘redux-saga‘
import * as reducer from ‘../reducer/users‘;

import rootSaga from ‘../sagas/sagas‘;

const sagaMiddleware = createSagaMiddleware();

const store = createStore(
  combineReducers(reducer),
  applyMiddleware(sagaMiddleware)
);

sagaMiddleware.run(rootSaga);

export default store;

然后在入口文件使用 store

src/index.js

import {Provider} from ‘react-redux‘;
import store from ‘./redux/store/store‘;
// 省略其他

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>, document.getElementById(‘root‘)
);

在 App.js 中获取 action 和 状态

import {registerAction, loginAction} from ‘../../redux/action/users‘;
import {connect} from "react-redux";
import {bindActionCreators} from "redux";
 //省略其他

class App extends Component {

  render(){
    return(
      <div className="App">
        //省略
      </div>
    )
  }

}

export default connect(
  (state) => {
// 获取状态   state.users  是指 reducer/users.js 文件中导出的 users
// 可以 `console.log(state);` 查看状态树
  return { users: state.users }
},
  (dispatch) => {
  return {
// 创建action
    registerActions: bindActionCreators(registerAction, dispatch),
    loginActions: bindActionCreators(loginAction, dispatch),
  }
})(App);
// 在App 组件的props里就有 this.props.users  this.props.registerActions this.props.loginActions 了
// 需要注意的是这里this.props.users是Immutable 对象,取值需要用this.props.users.get(‘newUser‘) 
// 也可在 reducer 里改用 js 普通对象

装饰器版本:
需要在Babel中开启装饰器
装饰器插件babel-plugin-transform-decorators-legacy

@connect(
  (state) => {
    console.log(state);
    return ({
      users: state.users,
    });
  },
  {registerActions: registerAction, loginActions: loginAction}
)

最后把 registerActions 传给RegisterDialog子组件,

src/components/Index/RegisterDialog.js

// 省略其他代码
 handleSubmit = (e) => {
    e.preventDefault();
    // 验证表单数据
    this.refs.user.validate((valid) => {
      if (valid) {
        // this.state.user 为表单收集的 用户注册数据
        this.props.registerActions(this.state.user);
        this.setState({loading: true});
      }
    });
  };

流程是:

  • 调用 action
    this.props.registerActions(this.state.user);
    返回action 为
{
    type:REGISTER_USER,
    data: this.state.user,
}
  • reducer 根据action类型更新状态
switch (action.type) {
    case REGISTER_USER:
      return state.merge({
        ‘newUser‘: action.data,
        ‘saveSuccess‘: false,
        ‘error‘: null,
      });
//省略其他代码

这时我们的store里的状态 newUser就被更新为 注册弹窗里收集的数据
到这里都还是同步的action,而注册是一个异步的操作。
下篇文章会介绍如何使用 redux-saga 进行异步操作。
redux-saga 已经在使用了,有兴趣的可以自行查看代码理解。

记得点star:)
项目代码地址:https://github.com/DigAg/digag-pc-react
vue2版项目代码地址:https://github.com/DigAg/digag-pc-vue2
相应后端项目代码地址:https://github.com/DigAg/digag-server

以上是关于React项目实践(一)之项目创建的主要内容,如果未能解决你的问题,请参考以下文章

React.js 项目实践——创建个人作品集网页

React.js 个人作品集项目实践

React之使用脚手架启动页面

练习案例React一创建React项目

React 实践项目

手把手教你创建Ant Design Pro的React项目