是否可以使用引用作为react组件的prop或状态?

时间:2019-10-22 08:14:20

标签: javascript reactjs next.js

我想创建反应表组件,其值是从单个数组对象派生的。是否可以从视图侧控制组件?我的目标是让每个在Web浏览器中使用此组件的用户都通过单例视图对象共享相同的数据。

程序建模如下。

  1. 数据库-服务器中只有一个数据库,其中包含已消失且独立的值。

  2. DataView-有单例视图类,该类反映数据库的表和其他相关数据,例如(总和,平均值)

  3. 表-我将构建类似于表的react组件。它将显示具有支持的排序,过滤,编辑和删除行功能(以及更多功能)的View数据。 它也没有实际数据,仅引用View中的数据(通过浅表复制-这是我的问题,可以吗?)

我的意图是, -当用户从表中更改值时,View向数据库查询,如果成功,View将引用更新的数据并将其值更改为新值,并通知Table重绘它的内容。 -我的意思是redraw,而不是updating value and redraw。 -当通过用户请求通过数据库交互更改View中的值时,无需更新组件的值,因为组件实际上不具有值,仅具有对值的引用(如C的指针)。因此,仅View要做的只是对Component说以重绘其内容。

我听说React的组件prop应该是不可变的。 (否则,state是可变的)我的目标是将对组件实际值的引用存储到其props中,以便没有用于将View的数据反映到表中的其他操作。

这是概念问题,我想知道是否有可能。由于javascript正式不支持指针(是吗?),所以我不确定是否可能。

View类如下,

const db_pool = require('instantiated-singleton-db-pool-interface')
class DataView {
  constructor() {
    this.sessions = ['user1', 'user2'] // Managing current user who see the table
    this.data = [ // This is View's data
    {id:1, name:'James', phone:'12345678', bank:2000, cash:300, total:2300,..},
    {id:2, name:'Michael', phone:'56785678', bank:2500, cash:250, total:2300,..},
    {id:3, name:'Tyson', phone:'23455432', bank:2000, cash:50, total:2300,..}
    ] // Note that 'total' is not in db, it is calculated --`dependent data`
  }
  notifySessionToUpdate(ids) {
    // ids : list of data id need to be updated
    this.sessions.forEach((session) => {
      session.onNotifiedUpdateRow(ids) // Call each sessions's 
    })
  }
  requestUpdateRow(row, changed_value) {
    // I didn't write async, exception related code in this function for simple to see.
    update_result = db_pool.update('UPDATE myTable set bank=2500 where id=1')
    if (update_result === 'fail') return; // Do Nothing

    select_result = db_pool.select('SELECT * from myTable where id=1') // Retrieve updated single data which object scheme is identical with this.data's data
    for (k in Object.keys(select_result)) {.ASSIGN_TO_row_IF_VALUE_ARE_DIFFERENT.} // I'm not sure if it is possible in shallow copy way either.
    calc.reCalculateRow(row) // Return nothing just recalculate dependant value in this.data which is updated right above.
    // Notify to session
    this.notifySessionToUpdate([1]) // Each component will update table if user are singing id=1's data if not seeing, it will not. [1] means id:1 data.
    return // Success
  }
... // other View features
}

关于会话部分,我正在检查如何实现与服务器进行通信的每个用户及其组件的sessionizing(?)。因此,我无法提供进一步的代码。抱歉。我正在考虑在UserViewReact Component Table之间实现另一个浅表复制DataView(而且我认为这样做有助于处理用户内容信息,例如排序首选项等)

关于DB代码,是将其嵌套在池和查询接口中的类。

我的问题是我对javascript不熟悉。因此,我不确定在我遇到的所有情况下,浅表副本实际上是否可以实现。

我需要考虑一下, 1. javascript是否以一致的方式完全支持shallowcopy?我的意思是像指针一样,保证检查值是否为参考。 2.剂量反应的成分可以这样使用吗?是否使用propsstate可以满足要求吗?

实际上,我坚决不可能这样做。但我想检查一下您的意见。好像是C语言一样的思维方式。

1 个答案:

答案 0 :(得分:0)

重画意味着重新渲染。您可以公开setState()组件中的dispatch()Table函数,并使用引用在View级别调用它们:

function View() {
  const ref = useRef();

  const onDbResponse = data => ref.current.update(data);

  return (
    <Table ref={ ref } />
  );
}

const Table = React.forwardRef((props, ref) => {
  const [ data, setData ] = useState([]);
  useImperativeHandler(ref, {
    update: setData
  });

  ...
});

无论如何,我不认为这样更新是一个好习惯。为什么不能只将数据放在某个全局上下文中并在那使用呢?

const Context = React.createContext({ value: null, query: () => {} });

const Provider = ({ children }) => {
  const [ value, setValue ] = useState();
  const query = useCallback(async (request) => {
    setValue(await DB.request(request));
  }, [ DB ]);

  const context = { value, query };

  return <Context.Provider value={ context }>{ children }</Context.Provider>;
}

const useDB = () => useContext(Context);

const View = () => {
  const { request } = useDB();

  request(...);
}

const Table = () => {
  const { value } = useDB();

  ...
}