写在前头

redux 简介

随着 JavaScript 单页应用开发日趋复杂,JavaScript 需要管理比任何时候都要多的 state (状态)。 这些 state 可能包括服务器响应、缓存数据、本地生成尚未持久化到服务器的数据,也包括 UI 状态,如激活的路由,被选中的标签,是否显示加载动效或者分页器等等。

管理不断变化的 state 非常困难。如果一个 model 的变化会引起另一个 model 变化,那么当 view 变化时,就可能引起对应 model 以及另一个 model 的变化,依次地,可能会引起另一个 view 的变化。直至你搞不清楚到底发生了什么。state 在什么时候,由于什么原因,如何变化已然不受控制。 当系统变得错综复杂的时候,想重现问题或者添加新功能就会变得举步维艰。

如果这还不够糟糕,考虑一些来自前端开发领域的新需求,如更新调优、服务端渲染、路由跳转前请求数据等等。前端开发者正在经受前所未有的复杂性,难道就这么放弃了吗?当然不是。

这里的复杂性很大程度上来自于:我们总是将两个难以理清的概念混淆在一起:变化和异步。 如果把二者分开,能做的很好,但混到一起,就变得一团糟。一些库如 React 试图在视图层禁止异步和直接操作 DOM 来解决这个问题。美中不足的是,React 依旧把处理 state 中数据的问题留给了我们自己。而 redux 就可以来帮我管理这些状态;

demo 演示

demo 结构树
├── config-overrides.js
├── .gitignore
├── package.json
├── package-lock.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ └── manifest.json
├── README.md
└── src
 ├── App.js
 ├── Demo
 │ ├── actionCreate.js
 │ ├── Demo.jsx
 │ ├── react-redux.js
 │ ├── reducer.js
 │ ├── redux.js
 │ ├── style.css
 │ └── thunk.js
 └── index.js

一、 redux API createStore 的实现

  首先我们先结合 reducer 以及 action 的知识简单实现开头展示的 demo, 并逐步揭晓 createStore 的神秘面纱;

1.1 准备工作:

创建 reducer 并导出 reducer
// reducer.js
const initState = { user: 'qianyin', age: 18, sex: '男' };
export const reducer = (state=initState, action) => {
 switch(action.type){
 case 'USER_UPDATE':
  return {...state, ...action.payload};
 case 'AGE_GROW':
  return {...state, age: state.age   1};
 case 'SEX_UPDATE':
  return {...state, ...action.payload};
 default:
  return state;
 }
}
创建 action 创建函数
// actionCreate.js
export const changeUser = (user) => {
 return {
 payload:{user},
 type: 'USER_UPDATE',
 };
}

export const changeAge = () => {
 return { type: 'AGE_GROW' };
}
通过 react 在页面上预先绘制出基本的元素
/* style.css */
.btn{
 height: 31px;

}
.input{
 height: 25px;
}
// Demo.jsx
import React from 'react';
import './style.css';

export default class Demo extends React.Component{
 onChange = () => {}
 onClick = () => {}
 render(){
 return (
  <div>
  <p>user: xxx, age: xxx</p>
  user: 
  <input type="text" className="input" onChange={this.onChange}/>
  &nbsp;
  <button className="btn" onClick={this.onClick}>年龄增长</button>
  </div>
 );
 }
}
最终页面将渲染如下:

1.2 demo 的初次实现代码

  • 创建全局状态 state;
  • 创建监听队列;
  • 针对监听队列,新增函数用于将指定监听对象添加到队列中;
  • 在函数 dispatch 中执行 reducer 将返回值作为新的 state, 同时依次执行监听对象;
  • 默认执行一次 dispatch 给定一个 type 相对唯一的 action, 目的是为了匹配 reducer 的默认状态值,从而实现对 redux state 的初始化;
  • 在组件 Demo 通过在函数 update 使用 this.setState 将全局 state 保存到 react state 中,并将函数 update 添加到监听队列中;从而使得当我们一旦试图通过 dispatch 修改全局状态时,能够及时更新 react state 最终触发 react 生命周期 render;
  • 在 react 生命周期 componentDidMount 中我们除了将 update 添加到监听队列以外,还需手动执行一次 update 其主要目的就是为了首次初始化 react state;
// Demo.jsx
import React from 'react';
import { changeAge, changeUser } from './actionCreate';
import { reducer } from './reducer';
import './style.css';

let state;
const listeners = [];
const subscribe = (listener) => {
 listeners.push(listener);
}
const dispatch = (action) => {
 state = reducer(state, action);
 console.log(state);
 listeners.forEach(v => v());
}
dispatch({type: '%$&HJKAJJHDJHJ'});

export default class Demo extends React.Component{
 state = {user: 'xxx', age: 'xxx'};
 componentDidMount(){
 subscribe(this.update);
 this.update();
 }

 update = () => {
 this.setState(state);
 }

 onChange = (e) => {
 dispatch(changeUser(e.target.value));
 }

 onClick = () => {
 dispatch(changeAge());
 }

 render(){
 return (
  <div>
  <p>user: {this.state.user}, age: {this.state.age}</p>
  user: 
  <input type="text" className="input" onChange={this.onChange}/>
  &nbsp;
  <button className="btn" onClick={this.onClick}>年龄增长</button>
  </div>
 );
 }
}

1.3 API createStore 的实现

其实上文的代码中对于 createStore 的实现原理已经基本描述清除,下面我们只是单纯的对代码进行了简单的封装;当然为了能够获取到 state 我们专门增加了一个函数 getState 来实现它;

createStore 函数实现
// redux.js

export const createStore = (reducer) => {
 // 声明常量
 let state;
 const listeners = [];

 // 获取状态
 const getState = () => {
 return state;
 }

 // 添加监听对象
 const subscribe = (listener) => {
 listeners.push(listener);
 }

 // [1]执行reducer修改状态 [2]遍历执行监听对象
 const dispatch = (action) => {
 state = reducer(state, action);
 listeners.forEach(v => v());
 }

 // 初始化 state
 dispatch({type: '%$&HJKAJJHDJHJ'});
 
 // 暴露接口
 return {getState, subscribe, dispatch};
}
调用 createStore 并对 demo 进行修改
// Demo.jsx
import React from 'react';
import './style.css';
import { changeAge, changeUser } from './actionCreate';
import { reducer } from './reducer';
import { createStore } from './redux';

const store = createStore(reducer);

export default class Demo extends React.Component{
 state = {user: 'xxx', age: 'xxx'};
 componentDidMount(){
 store.subscribe(this.update);
 this.update();
 }

 update = () => {
 this.setState(store.getState());
 }

 onChange = (e) => {
 store.dispatch(changeUser(e.target.value));
 }

 onClick = () => {
 store.dispatch(changeAge());
 }

 render(){
 return (
  <div>
  <p>user: {this.state.user}, age: {this.state.age}</p>
  user: 
  <input type="text" className="input" onChange={this.onChange}/>
  &nbsp;
  <button className="btn" onClick={this.onClick}>年龄增长</button>
  </div>
 );
 }
}

二、 react-redux API Provider 的实现

在 react 中大多数情况下我们需要将状态传递给后代组件进行使用的,当然通过 props 是可以实现状态从父级到子级的传递,但是当状态需要传递的层级比较深的情况下再使用 props 就显得无力了,那么在 react-redux 中它是如何实现对 store 的传递的呢?

2.1 react context 的引入

在 App.js 中创建 store 并通过 context 传递 store
// App.js
import React, { Component } from 'react';
import propTypes from 'prop-types';
import { createStore } from './Demo/redux';
import { reducer } from './Demo/reducer';
import Demo from './Demo/Demo';

// 创建 store
const store = createStore(reducer);

class App extends Component {
 // 声明 childContextTypes 状态属性类型
 static childContextTypes = {
 store: propTypes.object
 };
 // 设置 childContext
 getChildContext(){
 return {store}
 }
 render() {
 return <Demo />;
 }
}
export default App;
在子组件 Demo 中通过 context 获取 store 并对代码进行简单修改
// Demo.jsx
import React from 'react';
import propTypes from 'prop-types';
import './style.css';
import { changeAge, changeUser } from './actionCreate';

export default class Demo extends React.Component{
 // 设置 context 状态值类型
 static contextTypes = {
 store: propTypes.object
 };

 constructor(props, context){
 super(props, context);
 // 获取store
 this.store = context.store;
 this.state = {user: 'xxx', age: 'xxx'};
 }
 
 componentDidMount(){
 this.store.subscribe(this.update);
 this.update();
 }

 update = () => {
 this.setState(this.store.getState());
 }

 onChange = (e) => {
 this.store.dispatch(changeUser(e.target.value));
 }

 onClick = () => {
 this.store.dispatch(changeAge());
 }

 render(){
 return (
  <div>
  <p>user: {this.state.user}, age: {this.state.age}</p>
  user: 
  <input type="text" className="input" onChange={this.onChange}/>
  &nbsp;
  <button className="btn" onClick={this.onClick}>年龄增长</button>
  </div>
 );
 }
}

2.2 封装代码实现 Provider

通过 react context 我们实现了对 store 的传递,到这里 Provider 的功能以及实现原理基本上应该算是清晰了,无非就是对组件进行包裹同时通过 react context 来传递共享 store;那么接下来我们通过对代码的封装来实现 Provider 组件;

Provider 组件:实现对 store 的传递
// react-redux.js
import React from 'react';
import propTypes from 'prop-types';

export class Provider extends React.Component{
 // 设置 childContext 状态值类型
 static childContextTypes = {
 store: propTypes.object
 };

 // 设置 childContext
 getChildContext(){
 return {store: this.props.store}
 }
 
 render(){
 return this.props.children;
 }
}
重写 App.js: 对 Provider 组件的调用
// App.js
import React, { Component } from 'react';
import { createStore } from './Demo/redux';
import { Provider } from './Demo/react-redux';
import { reducer } from './Demo/reducer';
import Demo from './Demo/Demo';

// 创建 store
const store = createStore(reducer);

class App extends Component {
 render() {
 // 调用接口 Provider
 return <Provider store={store}><Demo /></Provider>;
 }
}
export default App;

三、 react-redux API connect 高阶组件的实现

上文中在后代组件如果需要获取 store 则需要手动通过获取 react context 来调用 store 并且需要显性的调用 store 内部的方法来进行一些操作;接下来我们来实现这么一个高阶组件 connect,我们只需要提供所需的 redux state 以及 action 创建函数,即可通过 props 获取到相应的 redux state , 并且允许直接通过 props 调用action 创建函数来试图修改 redux state ;

创建高阶组件 connect
// react-redux.js
export const connect = (mapStateToProps, mapDispatchToProps) => (Component) => {
 return class NewComponent extends React.Component{
 render(){
  return <Component />
 }
 }
}
获取store
// react-redux.js
export const connect = (mapStateToProps, mapDispatchToProps) => (Component) => {
 return class NewComponent extends React.Component{
 // 设置 context 状态值类型
 static contextType = {
  store: propTypes.object
 };
  // [1]获取 store [2]设置空 react state
 constructor(props, context){
  super(props, context);
  this.store = context.store;
  this.state = {};
 }
 render(){
  return <Component />
 }
 }
}
添加监听对象,并尝试通过 props 将状态传递给子组件
export const connect = (mapStateToProps, mapDispatchToProps) => (Component) => {
 return class NewComponent extends React.Component{
 static contextType = {
  store: propTypes.object
 };
 constructor(props, context){
  super(props, context);
  this.store = context.store;
  this.state = {};
 }
  // [1]添加监听对象 [2]手动执行监听对象,初始化 react state
 componentDidMount(){
  this.store.subscribe(this.update);
  this.update();
 }
 
 update = () => {
  // 获取全部redux state 并添加到 react state
  const state = this.store.getState();
  this.setState(state);
 }
 render(){
  // 通过 props 将 react state 全部传给子组件
  return <Component {...this.state} />
 }
 }
}
通过 mapStateToProps 获取指定 redux state
// react-redux.js
export const connect = (mapStateToProps, mapDispatchToProps) => (Component) => {
 return class NewComponent extends React.Component{
 static contextType = {
  store: propTypes.object
 };
 constructor(props, context){
  super(props, context);
  this.store = context.store;
  this.state = {};
 }
 componentDidMount(){
  this.store.subscribe(this.update);
  this.update();
 }
 
 update = () => {
  // 执行 mapStateToProps 只获取用户指定需求的 state
  const state = this.store.getState();
  const filterState = mapStateToProps(state);
  this.setState(filterState);
 }
 render(){
  return <Component {...this.state} />
 }
 }
}
通过 mapDispatchToProps 获取 action 创建函数: 使用 dispatch 包裹后返回
// react-redux.js
// react-redux.js
export const connect = (mapStateToProps, mapDispatchToProps) => (Component) => {
 return class NewComponent extends React.Component{
 static contextTypes = {
  store: propTypes.object
 };
 constructor(props, context){
  super(props, context);
  this.store = context.store;
  this.state = {};
 }
 componentDidMount(){
  this.store.subscribe(this.update);
  this.update();
 }
 
 update = () => {
  // 处理 state ===> 获取用户指定的 state
  const state = this.store.getState();
  const filterState = mapStateToProps(state);

  // 使用 dispatch 对 mapDispatchToProps 中的 action 创建函数进行包裹后返回
  const actionFun = {};
  for(let key in mapDispatchToProps){
  actionFun[key] = (...args) => {
   this.store.dispatch(mapDispatchToProps[key](...args));
  }
  }
 // 一种简写方式: 骚操作
 // const actionFun = Object.keys(mapDispatchToProps)
 // .reduce((total, item) => {
 // return { ...total, [item]: (...args) => {dispatch(mapDispatchToProps[item](...args));}
 // } } ,{});

  this.setState({...filterState, ...actionFun});
 }
 render(){
  return <Component {...this.state} />
 }
 }
}
调用高阶组件:修改 Demo.jsx
// Demo.jsx
import React from 'react';
import { changeAge, changeUser } from './actionCreate';
import { connect } from './react-redux';
import './style.css';

// 编写 mapStateToProps 参数 redux state 返回所需的 redux state
const mapStateToProps = (state) => {
 return {user: state.user, age: state.age};
}

// 调用高阶组件
@connect(mapStateToProps, {changeAge, changeUser})
export default class Demo extends React.Component{
 onChange = (e) => {
 this.props.changeUser(e.target.value);
 }
 onClick = () => {
 this.props.changeAge();
 }
 render(){
 return (
  <div>
  <p>user: {this.props.user}, age: {this.props.age}</p>
  user: 
  <input type="text" className="input" onChange={this.onChange}/>
  &nbsp;
  <button className="btn" onClick={this.onClick}>年龄增长</button>
  </div>
 );
 }
}

四、redux API bindactioncreators 的实现

在上文我们对 mapDispatchToProps 的处理过程就是 API bindactioncreators 的功能: 将给定 action 创建函数使用 dispatch 进行包裹后返回;

封装 bindactioncreators
// redux.js
export const bindactioncreators = (mapDispatchToProps, dispatch) => {
 const actionFun = {};
 // 遍历 mapDispatchToProps 中每个 action 创建函数 并使用 dispatch 包裹后返回
 for(let key in mapDispatchToProps){
 actionFun[key] = (...args) => {
  dispatch(mapDispatchToProps[key](...args));
 }
 }

 return actionFun;
 // 一种简写方式: 骚操作
 // return actionFun = Object.keys(mapDispatchToProps)
 // .reduce((total, item) => {
 // return { ...total, [item]: (...args) => {dispatch(mapDispatchToProps[item](...args));}
 // } } ,{});
}
修改 connect :
// react-redux.js
import { bindactioncreators } from './redux';
....
export const connect = (mapStateToProps, mapDispatchToProps) => (Component) => {
 return class NewComponent extends React.Component{
 static contextTypes = {
  store: propTypes.object
 };
 constructor(props, context){
  super(props, context);
  this.store = context.store;
  this.state = {};
 }
 componentDidMount(){
  this.store.subscribe(this.update);
  this.update();
 }
 
 update = () => {
  const state = this.store.getState();
  const filterState = mapStateToProps(state);
  
  // 调用 API bindactioncreators 
  // 对 mapDispatchToProps 内每个 action 创建函数使用 dispatch 进行包裹后返回
  const actionFun = bindactioncreators(mapDispatchToProps, this.store.dispatch);
  this.setState({...filterState, ...actionFun});
 }
 render(){
  return <Component {...this.state} />
 }
 }
}

五、redux API applyMiddleware 的实现

到此简化版的 react-redux 算是已经初步完成,但是假如我们想要我们的 age 值的增长是一个异步操作,比如:通过按钮点击后经过两秒再修改 age ,而不是一点击按钮就立即修改值;这样我们又该怎么实现呢?

当然我们可以通过 setTimeout 两秒后再执行 action 创建函数,比如这样:

onClick = () => {
 setTimeout(()=>{
  // 两秒后执行 action 创建函数
  this.props.changeAge();
 }, 2000);
}

但是呢事实上我们并不愿意像上面那么整,我们想要这么一种效果:我们只需要简单的调用 action 创建函数即可实现异步操作,而不是需要进行额外的操作;这时我们就需要为我们的 react-redux 编写一个中间件来实现这么一个效果;

5.1 准备工作

新增action 创建函数

  在这之前我们所有的 acton 创建函数都是直接返回一个 action 对象,下面我们写一个不一样的 action 创建函数, 它返回的不再是一个 action 对象而是一个函数,并且该函数接收两个参数 dispatch 以及 getState, 在该函数内部我们进行相应的异步操作,比如:修改 age 值;

// actionCreate.js
export const asyncChangeAge = () => {
 // 返回函数
 return (dispatch, getState) => {
 setTimeout(v=>{
  console.log('==>', getState());
  dispatch({type: 'AGE_GROW'});
 }, 1000);
 }
}
修改页面:新增按钮并绑定点击事件,并且调用 asyncChangeAge 函数;
// Demo.jsx
// Demo.jsx
import React from 'react';
import './style.css';
// 导入 asyncChangeAge
import { changeAge, changeUser, asyncChangeAge } from './actionCreate';
import { connect } from './react-redux';

const mapStateToProps = (state) => {
 return {user: state.user, age: state.age};
}

// 添加 asyncChangeAge
@connect(mapStateToProps, {changeAge, changeUser, asyncChangeAge})
export default class Demo extends React.Component{
 onChange = (e) => {
 this.props.changeUser(e.target.value);
 }
 onClick = () => {
  this.props.changeAge();
 }
 // 点击事件
 onClickAsync = () => {
 this.props.asyncChangeAge();
 }
 render(){
 return (
  <div>
  <p>user: {this.props.user}, age: {this.props.age}</p>
  user: 
  <input type="text" className="input" onChange={this.onChange}/>
  &nbsp;
  <button className="btn" onClick={this.onClick}>年龄增长</button>
  {/* 新增按钮 */}
  <button className="btn" onClick={this.onClickAsync}>
   异步增长
  </button>
  </div>
 );
 }
}
页面的变化其实很简单就是新增了一个按钮:

5.2 需求实现

接下来我们先什么都不考虑先来实现我们的需求,现在 action 创建函数 asyncChangeAge 因为返回的是一个对象,其 type 值为 undefined 所以当我们点击按钮时 reducer 将会一直匹配到默认情况,返回的将是当前的状态,接下来我们先让我们的 action 创建函数 asyncChangeAge 生效,达到异步修改状态的作用;

扩展 createStore

既然 asyncChangeAge 返回的不再是一个 action 对象,而是一个函数;那么其实我们要做的事情是很简单的,我们只需要针对 createStore 中的返回值 dispatch 进行一个简单的扩展即可;通过判断 dispatch 中的 action 参数是否是函数而进行不同的操作:

// redux.js
export const createStore = (reducer) => {
 ......
 // 在createStore 我们对返回值 dispatch 进行了封装
 const dispatchExtend = (action) => {
 if(typeof action === 'function'){
  // action 为函数,执行函数
  action(dispatch, getState);
 } else {
  // action 为非函数(对象)调用dispatch
  dispatch(action);
 }
 }
 return {getState, dispatch: dispatchExtend, subscribe};
}

5.3 抽离封装

上文我们通过对 createStore 的返回值 dispatch 进行了扩展,实现了 redux-react 的异步操作,但问题是我们将代码写死在 createStore 中了,redux-react 的异步操作应该是一个可选项而不应该是必选项;

重新扩展 createStore :

新增参数 middleware (函数), 在函数 createStore 开始位置判断 middleware 是否存在,存在则执行;

// redux.js
export const createStore = (reducer, middleware) => {
 // 判断 middleware 是否存在,存在则执行
 if(middleware){
 return middleware(createStore)(reducer);
 }

 let state;
 const listeners = [];

 const getState = () => {
 return state;
 }

 const dispatch = (action) => {
 state = reducer(state, action);
 listeners.forEach(v => v());
 }

 const subscribe = (listener) => {
 listeners.push(listener);
 }

 dispatch({type: '%$&HJKAJJHDJHJ'});

 return {getState, dispatch, subscribe};
}
编写函数 applyMiddleware ,在创建 store 时 作为 createStore 第二参数
// App.js
const applyMiddleware = (createStore) => (redux)=> {
 // 在这里进行创建 store
 const store = createStore(redux);
 // 返回store
 return {...store}
}

const store = createStore(reducer, applyMiddleware);
在 applyMiddleware 函数内扩展 dispatch

上文 applyMiddleware 函数并其实没做任何事情, 只是在 createStore 函数外面套了一层函数,那么接下来我们做点正事,来扩展一下我们的 dispatch

// App.js
const applyMiddleware = (createStore) => (redux)=> {
 const store = createStore(redux);

 const midApi = {
 getState: store.getState,
 dispatch: (...args) => {dispatch(...args);}
 };

 const dispatch = (action) => {
 if( typeof action === 'function' ){
  action(midApi.dispatch, midApi.getState);
 } else {
  store.dispatch(action);
 }
 }

 return {
 ...store,
 dispatch
 };
}

5.4 扩展分离

上文已经实现了我们想要的效果了,我们在 applyMiddleware 对 dispatch 进行了扩展;然而我们是那么容易满足的嘛,当然不是的!! applyMiddleware 中对 dispatch 的扩展我们还可以将其单独提出来封装成一个函数;

重写 applyMiddleware ,再给 applyMiddleware 包裹一层函数: 将对 dispatch 的扩展抽离,封装成方法;
// App.js
const applyMiddleware = (middleware) => (createStore) => (redux)=> {
 const store = createStore(redux);

 const midApi = {
 getState: store.getState,
 dispatch: (...args) => {dispatch(...args);}
 };

 const dispatch = middleware(midApi)(store.dispatch);

 return {
 ...store,
 dispatch
 };
}
thunk 中间件: 其实 thunk 才是真正的中间件;applyMiddleware 只是用来绑定中间件的
// App.js 
const thunk = ({dispatch, getState}) => next => (action) => {
 if(typeof action === 'function'){
 action(dispatch, getState);
 } else {
 next(action);
 }
}; 
在调用 createStore 时绑定中间件 thunk
// App.jsx
const store = createStore(reducer, applyMiddleware(thunk));

5.5 代码整理

这一步只是将 applyMiddleware 函数移到 redux.js 文件中;同时将 thunk 函数写到文件 thunk.jsx 中,然后在 App.js 中引用 applyMiddleware 以及 thunk 而已;

看下最终效果(效果和上一个录屏是一样样的)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持Devmax。

浅谈redux以及react-redux简单实现的更多相关文章

  1. ios – React native链接到另一个应用程序

    如果是错误的,有人知道如何调用正确的吗?

  2. ios – React Native – 在异步操作后导航

    我正在使用ReactNative和Redux开发移动应用程序,我正面临着软件设计问题.我想调用RESTAPI进行登录,如果该操作成功,则导航到主视图.我正在使用redux和thunk所以我已经实现了异步操作,所以我的主要疑问是:我应该把逻辑导航到主视图?我可以直接从动作访问导航器对象并在那里执行导航吗?.我对组件中的逻辑没有信心.似乎不是一个好习惯.有没有其他方法可以做到这一点?

  3. 在ios中使用带有React Native(0.43.4)的cocoapods的正确方法是什么?

    我已经挖掘了很多帖子试图使用cocoapods为本地ios库设置一个反应原生项目,但我不可避免地在#import中找到了丢失文件的错误.我的AppDelegate.m文件中的语句.什么是使用反应原生的可可豆荚的正确方法?在这篇文章发表时,我目前的RN版本是0.43.4,而我正在使用Xcode8.2.1.这是我的过程,好奇我可能会出错:1)

  4. ios – 使用react-native-router-flux和redux,如何更新视图组件中的状态?

    为了完整起见,整个代码可以在github找到.解决方法您可能忘记将Launch组件连接到商店.你想要做的是类似于你在ExampleContainer中所做的,即然后正确的值将显示在您的日志中

  5. ios – React Native WebView滚动行为无法按预期工作

    如何确保滚动事件的行为与ReactNative应用程序中的浏览器相同?

  6. ios – React Native – BVLinearGradient – 找不到’React/RCTViewManager.h’文件

    谢谢.解决方法几天前我遇到了完全相同的问题.问题是在构建应用程序时React尚未链接.试试这个:转到Product=>Scheme=>管理方案…=>点击你的应用程序Scheme,然后点击Edit=>转到Build选项卡=>取消选中ParallelizeBuild然后点击标志添加目标=>搜索React,选择第一个名为React的目标,然后单击Add然后在目标列表中选择React并将其向上拖动到该列表中的第一个.然后转到Product=>再次清理并构建项目.这应该有所帮助.

  7. ios – React Native – NSNumber无法转换为NSString

    解决方法在你的fontWeight()函数中也许变成:

  8. ios – React native error – react-native-xcode.sh:line 45:react-native:command not found命令/ bin/sh失败,退出代码127

    尝试构建任何(新的或旧的)项目时出现此错误.我的节点是版本4.2.1,react-native是版本0.1.7.我看过其他有相同问题的人,所以我已经更新了本机的最新版本,但是我仍然无法通过xcode构建任何项目.解决方法要解决此问题,请使用以下步骤:>使用节点版本v4.2.1>cd进入[你的应用]/node_modules/react-native/packager>$sh./packager.s

  9. 反应原生 – 如何通过Xcode构建React Native iOS应用程序到设备?

    我试图将AwesomeProject应用程序构建到设备上.构建成功并启动屏幕显示,但后来我看到一个红色的“无法连接到开发服务器”屏幕.它表示“确保节点服务器正在运行–从Reactroot运行”npmstart“.看起来节点服务器已经运行,因为当我做npm启动时,我收到一个EADDRINUSE消息,表示该端口已经在使用.解决方法从设备访问开发服务器您可以使用开发服务器快速迭代设备.要做到这一点,你的

  10. 静音iOS推送通知与React Native应用程序在后台

    我有一个ReactNative应用程序,我试图获得一个发送到JavaScript处理程序的静默iOS推送通知.我看到的行为是AppDelegate中的didReceiveRemoteNotification函数被调用,但是我的JavaScript中的处理程序不会被调用,除非应用程序在前台,或者最近才被关闭.我很困惑的事情显然是应用程序正在被唤醒,并且它的didReceiveRemoteNotifi

随机推荐

  1. js中‘!.’是什么意思

  2. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  3. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  4. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. AngularJs上传前预览图片的实例代码

    使用AngularJs进行开发,在项目中,经常会遇到上传图片后,需在一旁预览图片内容,怎么实现这样的功能呢?今天小编给大家分享AugularJs上传前预览图片的实现代码,需要的朋友参考下吧

  6. JavaScript面向对象编程入门教程

    这篇文章主要介绍了JavaScript面向对象编程的相关概念,例如类、对象、属性、方法等面向对象的术语,并以实例讲解各种术语的使用,非常好的一篇面向对象入门教程,其它语言也可以参考哦

  7. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  8. javascript 动态调整图片尺寸实现代码

    在自己的网站上更新文章时一个比较常见的问题是:文章插图太宽,使整个网页都变形了。如果对每个插图都先进行缩放再插入的话,太麻烦了。

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. React学习之受控组件与数据共享实例分析

    这篇文章主要介绍了React学习之受控组件与数据共享,结合实例形式分析了React受控组件与组件间数据共享相关原理与使用技巧,需要的朋友可以参考下

返回
顶部