React组件间传递数据确比较恼火目前基本通props传递所必须buttonlistitem共父组件设置state再通传递父组件定义事件处理函数更新状态通状态更新触发组件更新……复杂看jsfiddle
最后给出另一个例子,试着理解它。
方法一:导出 store
这应该是最简单省事同时也容易想到的方法,但是有一点需要注意:
不要在服务端渲染中使用该方法
如果你在使用服务端渲染的 app 中直接导出 store,那么 app 的所有 user 都会获得一个单例的 store (包括相同的 JWT Token),这肯定不是你乐见的。
除去上述这种情况,当我们需要获取 store 中的 JWT Token 时,可以这么做:
/
storejs
/
import { createStore } from 'redux';
import reducer from '/reducer';
const store = createStore(reducer);
export default store;
1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9
创建 store 的方法还和以前一样,仅仅是导出它,以便于在其他文件中使用。
不要担心你使用的 createStore 方法可能会很复杂,放心的使用各种中间件比如 thunk, saga, devtools ,你需要做的仅仅是导出 store 而已。
紧接着,在需要用到 store 中数据的地方,引入 (import) 它。下面的例子就是我们在一个普通函数 apijs 中将 store 中的 JWT Token 通过 ajax 传递给服务端。
/
apijs
/
import store from '/store';
export function getProtectedThing() {
// grab current state
const state = storegetState();
// get the JWT token out of it
// (obviously depends on how your store is structured)
const authToken = statecurrentUsertoken;
// Pass the token to the server
return fetch('/user/thing', {
method: 'GET',
headers: {
Authorization: `Bearer ${authToken}`
}
})then(res => resjson());
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
在 Redux 官网的 FAQ 中有这样一个问题 我可以在组件中直接引入 store 并使用吗 ?
其实如果需要在 React 组件中使用 store,我们有更好的选择 (译者注:也是官方提倡的):那就是使用 React-Redux 中的 connect 方法。
Mark Erikson,Redux 的维护者之一,在 Reddit 上就这个问题发表过如下看法:
通常情况下,不建议在 component 中通过 import 的方式来使用 store
在某些情况下,可以试着通过 thunk 或者其他一些 Redux 中间件来 *** 作 store 而不是直接去引用它。
但是凡事总有例外,打我自己的比方,有一个项目中 70% 的代码使用 Backbone 写的,在项目的一些模块中,我们同时需要来自 Backbone models 和 Redux store 中的数据,在这部分模块中,我们的确需要 import {store} from “store” 这种直接的引用方式,因为我们的确没有其他选择。
所以,直接引用并不是理想的方式,但是,如果有必要,也可以。
React Component 之外 dispatch action
如果你在 React Component 之外需要 dispatch action,那么同样的方法也是适用的:引入 store 然后再调用 storedispatch(),这和你在 react-redux 中通过 connect 函数获取到 dispatch 是一样的。
方法二:从 thunk 中获取 redux 的 state
如果你需要在 thunk 中获取 redux store 中的某项数据,更简单不过。你根本不需要直接引入 store,因为 thunk 的 action 中有一个 getState 的输入参数。
下面的例子就是从 thunk 的 action 创建函数中获取 JWT Token
/ actionsjs /
export function getProtectedThing() {
return (dispatch, getState) => {
// grab current state
const state = getState();
// get the JWT token out of it
// (obviously depends on how your store is structured)
const authToken = statecurrentUsertoken;
// Pass the token to the server
return fetch('/user/thing', {
method: 'GET',
headers: {
Authorization: `Bearer ${authToken}`
}
})then(res => resjson());
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
另外,如果你不想在 thunk 的 action 函数中直接使用 fetch,你可以选择将 fetch 封装到另外一个类中比如 apijs 当然你需要额外的参数将所需数据传递出去。
方法三:使用中间件(middleware)截获 action 中的数据
如果你不喜欢上述两种方法 (或是无法使用),那么也可以试试下面这种方法。
开发一个自定义的 redux 中间件,“拦截” 特定的 action 在 action 触达 store 之前获取其携带的数据,甚至在中间件中直接获取 store
我们还以 JWT Token 为例。假设应用程序在用户成功登陆后会触发一个 LOG_SUCCESS 的 action,该 action 携带的数据包含 JWT Token
/
indexjs
/
const saveAuthToken = store => next => action => {
if(actiontype === 'LOGIN_SUCCESS') {
// after a successful login, update the token in the API
apisetToken(actionpayloadauthToken);
}
// continue processing this action
return next(action);
}
const store = createStore(
reducer,
applyMiddleware(saveAuthToken)
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
在你的 apijs 中会有一个 setToken 的方法将 token 赋值给本地变量。
/
apijs
/
let currentAuthToken = null;
export function setToken(token) {
currentAuthToken = token;
}
export function getProtectedThing() {
// Pass the token to the server
return fetch('/user/thing', {
method: 'GET',
headers: {
Authorization: `Bearer ${currentAuthToken}`
}
})then(res => resjson());
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
如果你使用的 >
在 react中 通过 state 以及 setState() 来控制组件内部数据的状态,其实也可以使用类似全局变量的方式在 constructor 里定义,但是全局变量的污染性都是知道的,所以 react 内部这种 state 和 setState 还是很优秀的数据驱动页面模式。
state
state 是 react 组件内部用来存储数据状态的,与 vue 中的 data 类似。但他们的更新机制差别很大, vue 中可以直接改变 data , vue 内部的 watcher 机制会监听到这些数据的变化从而刷新页面,而 react 则是手动驱使 setState 去改变内部的 state ,从而使得页面刷新。
1state的作用
state 是 React 组件的一个对象, React 把用户界面当做是状态机,想象它有不同的状态然后渲染这些状态,从而可以轻松让用户界面与数据保持一致。
React 中,更新组件的 state ,会导致重新渲染用户界面(不要 *** 作 DOM )简单来说,就是用户界面会随着 state 变化而变化
2state工作原理
常用的通知 React 数据变化的方法是调用 setState(data,callback) ,这个方法会合并 data 到 thisstate ,并重新渲染组件。渲染完成后,调用可选的 callback 回调。大部分情况不需要提供 callback ,因为 React 会自动把界面更新到最新状态。
setState()
与 vue 中不同的是 state 不能直接被修改,需要通过 setState() 的方法去修改。
1、 setState() 更新组件状态之后不会立即生效, react 为了提高性能会按批次更新 state 然后 render , 即异步 *** 作,所以同时写两个 setState 并不会触发两次,而是会合并处理。因此 setState() 之后立即去取 state 的值并不是更新之后的状态。
2、 setState() 第一个参数接受两种类型的参数, Object 以及 Function
当参数是 Object 的时候, 可以即为对应 state 中的 key , value 即是新的值。
Function
当参数是函数的时候, setState() 会将上一个 setState() 的结果作为参数传入这个函数
setState() 第二个参数是一个回调函数,表示 state 更新完成
看到这个回调函数,我们可以想象到很多场景,当页面更新完成后才进行的某些处理,将异步 *** 作变为同步,而这也可以和 await/async 结合使用
在 react 中更新页面是一个很复杂的 *** 作, vue 也是,全局更新和部分更新,目前感觉还没有哪种语言能非常智能的知道准确的要更新哪一部分内容,但是 react 的机制优秀的就在于 js *** 控的虚拟 dom ,即使是全局更新,也是很快速的更新。
以上就是关于React子组件取不到父组件的state的值,求解全部的内容,包括:React子组件取不到父组件的state的值,求解、react怎么在其他文件里获取store变量、state和setState分析等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)