如何安全地使用 React 的 context
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何安全地使用 React 的 context相关的知识,希望对你有一定的参考价值。
1. 父组件 -> 前几层子组件: props2. 父组件 -> 非常深入的子组件(比如从最顶层到第5层以后): context
这种情况几乎很少见,除非写框架或者工具,最好是只用props,清晰明了
3. 子组件 -> 父组件:callback
4. 子组件时间: 严格意义上不存在这种情况,如果出现这样的需求,说明你的写法是错误的,
数据的流向始终都应该是从顶至下。例如root -> (A,B,C) 所以A组件改变,需要让B改变时,A调用root以props传来的callback从而导致root的state发生变化,这样B就能得到更新
5.
当APP复杂的可能特殊情况:在使用pureRenderMixin来提升渲染速度的时候,非常里层的子组件需要一些参数来计算显示的值,但是你又不需要
当这个值改变的时候重新渲染这个组件而且也不想用context的时候, 在Root中定义this.getAllState= () =>
this.state, 然后将这个getAllState作为props传递给子组件; 这种情况很少出现,慎用
6.使用某种Flux,让局部组件链接一个自己的store,同时接受来自父组件的各种callback props, 通过这些callback实现 小组件的store改变时,通知父组件
在一个实际的APP中的实际情况是如何设计store和props的呢?
其实重点,我认为是store和store之间是如何交流数据的。
这里我斗胆地拿我在家写的一个编辑器来做一些分析:编辑器端Flommox, 播放器向redux迁移中
整个编辑器网站分成了不同的页面,每个页面(例如/course:id, /editor/:id, /quizs)对应一个Action分组+一个Store, 有的复杂页面可能需要很多歌store整个编辑器网站分成了不同的页面,每个页面(例如/course:id, /editor/:id, /quizs)对应一个Action分组+一个Store, 有的复杂页面可能需要很多歌store
这
个编辑器使用了不止一个store,在初次渲染是先隐藏了『资源弹出框』『习题弹出框』他们分别有自己的store,但是他们是否显示是由父组件的
store控制的,具体的数据交流第6点已经简单的说明了。有些flux框架可以让一个函数作为Action,那么这个就可以作为callback进行数
据交流了。
更好的方式:直接在Action里传递Promise, 甚至Observable
更更好的方式:使用Redux 的middleware, 在一个Action发送途中去做异步请求其他store的数据,Redux的Action中也可以传递thunk, promise,Observable ,function等,尽量少用callback,让整个APP更加functional programming, 更好管理 参考技术A 我的理解是,适配工作应该由native代码来做,reactView只是基于nativeView的contex所创建出来的。
然后关于侦听虚拟导航栏的显示与隐藏,
这个问题第一个解决的应该是native代码如何侦听虚拟导航栏的出现与消失,然后在native的事件中调用facebook的
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, params);方法给JS代码发送事件,然后JS侦听该事件.
如何安全地引用 std::vector 元素?
【中文标题】如何安全地引用 std::vector 元素?【英文标题】:How I can safely reference to an std::vector element? 【发布时间】:2021-05-16 22:31:34 【问题描述】:我想创建一个为其他结构保持更高状态的结构。
我尝试这样创建它,但我最近发现返回指向 std::vector 元素的指针并不安全,因为该指针可以更改。
struct Foo
std::string &context;
std::string content;
Foo(std::string &context, std::string content) : context(context), content(content)
struct Bar
std::string context;
std::vector<std::string> manyFoos;
Foo* addFoo(std::string content)
manyFoos.emplace_back(context, content);
return &manyFoos[manyFoos.size() - 1];
struct Example
Bar bar;
Foo* fooA;
Foo* fooB;
Example()
fooA = bar.addFoo("Hello");
fooB = bar.addFoo("World");
有什么好的和安全的方法来做到这一点?
【问题讨论】:
使用其他容器代替 std::vector? ^^ 例如std::list<T>
标准库有什么替代品吗?
我刚才提到了一个
你可以拥有share_ptr的vector并返回weak_ptr,这样你可以确保正确的引用。
【参考方案1】:
有什么好的和安全的方法来做到这一点?
保存这对夫妇(矢量参考,Foo
的索引),假设 Foo
s 只添加在后面。
加上一点语法糖:
struct Bar
std::string context;
std::vector<Foo> manyFoos;
struct FooProxy
std::vector<Foo>& foos;
std::vector<Foo>::size_type index;
operator Foo() return foos[index];
;
auto addFoo(std::string content)
manyFoos.emplace_back(context, content);
return FooProxymanyFoos, manyFoos.size()-1;
;
Live example
【讨论】:
【参考方案2】:你可以拥有shared_ptr的向量并返回weak_ptr,这样你可以确保正确引用
#include <iostream>
#include <vector>
#include <memory>
struct Foo
std::string &context;
std::string content;
Foo(std::string &context, std::string content) : context(context), content(content)
;
struct Bar
std::string context;
std::vector<std::shared_ptr<Foo>> manyFoos;
std::weak_ptr<Foo> addFoo(std::string content)
auto foo = std::make_shared<Foo>(context, content);
manyFoos.emplace_back(foo);
return foo;
;
void printFoo(std::weak_ptr<Foo> foo)
// Here we are checking weak_ptr expiry
std::cout << (foo.expired() ? "Foo Expired" : foo.lock()->content) << std::endl;
int main()
Bar bar;
std::weak_ptr<Foo> fooA;
std::weak_ptr<Foo> fooB;
fooA = bar.addFoo("Hello");
fooB = bar.addFoo("World");
printFoo(fooA);
printFoo(fooB);
// erase last element
bar.manyFoos.pop_back();
printFoo(fooB);
return 0;
输出:
Hello
World
Foo Expired
【讨论】:
以上是关于如何安全地使用 React 的 context的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 websocket 安全地将我的 cli 应用程序连接到网站
如何使用 IConfidentialClientApplication 获取安全 Web API 的令牌
如何使用 TypeScript 以类型安全的方式访问 React 子元素道具?