如何安全地使用 React 的 context

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何安全地使用 React 的 context相关的知识,希望对你有一定的参考价值。

1. 父组件 -> 前几层子组件: props

2. 父组件 -> 非常深入的子组件(比如从最顶层到第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&lt;T&gt; 标准库有什么替代品吗? 我刚才提到了一个 你可以拥有share_ptr的vector并返回weak_ptr,这样你可以确保正确的引用。 【参考方案1】:

有什么好的和安全的方法来做到这一点?

保存这对夫妇(矢量参考,Foo 的索引),假设 Foos 只添加在后面。

加上一点语法糖:

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 子元素道具?

如何让音频在 React 中更流畅地循环播放?

如何使用 react-hook-form 有条件地禁用提交按钮?

如何使用 React 前端和 Spring Boot 安全后端进行客户端身份验证检查?