当前位置: 首页 > 知识库问答 >
问题:

URL哈希和Redux状态的双向绑定

广献
2023-03-14

我现在正在学习Redux和React,我正在写一个像这样的爱好项目。

该项目是一个使用标记进行搜索的搜索服务。用户可以在UI中添加或删除标记。在代码中,标记以Redux状态表示,添加和删除标记通过单独的操作进行。到目前为止还不错,我有一个玩具代码可以使用。

现在我想用哈希之后的URL部分“绑定”标签;例如,序列化标记,用破折号分隔;这样用户就可以复制/粘贴URL并拥有相同的标记。

我找不到如何轻易做到这一点。

我总是点击一个叫做“react router”的东西,但我在示例中看到的是,总是有更多的输入点指向应用程序,并根据散列向用户显示应用程序的不同部分。我不想那样。所以我不知道我是否真的需要这个路由器;我不想走任何路线。

即使我想要这个,我也找不到如何将Redux状态与URL绑定。我不想将标签直接注入组件的道具;我希望url中的标记处于Redux状态。

感觉好像我做错了什么,我需要重新思考我的整体设计,但我不知道从哪里开始。

(我没有添加任何实际代码,因为我认为这是关于应用程序设计的更一般的问题,但我可以稍后简化我的玩具代码并粘贴到这里)

共有2个答案

柯冯浩
2023-03-14

我从亚历山大·比科夫的答案中得到了灵感,redux坚持并使其成为一种增强器,它可以实现哈希的双向绑定

import { applyMiddleware } from 'redux';
import createActionBuffer from 'redux-action-buffer';

const CHANGE_HASH = '@@hashSynch/CHANGE_HASH';
const hashEnhancer = (hashFromState, stateFromStateAndHash) => createStore => (reducer, initialState) => {
  const store = createStore(liftReducer(reducer), initialState, applyMiddleware(createActionBuffer(CHANGE_HASH)));
  store.subscribe(() => {
    const hash = hashFromState(store.getState());
    if (window.location.hash !== hash) {
        window.location.hash = hash;
    }
  });

  window.addEventListener('hashchange', () => {
    const hash = window.location.hash;
    const savedHash = hashFromState(store.getState());
    if (savedHash !== hash) {
      store.dispatch({
        type: CHANGE_HASH,
        hash
      });
    }
  }, false);

  store.dispatch({
    type: CHANGE_HASH,
    hash: window.location.hash
  });

  function liftReducer(reducer) {
    return (state, action) => {
      if (action.type !== CHANGE_HASH) {
        return reducer(state, action);
      } else {
        return stateFromStateAndHash(state, action.hash);
      }
    }
  }

  return {
    ...store,
    replaceReducer: (reducer) => {
      return store.replaceReducer(liftReducer(reducer))
    }
  }
};

这样使用:

export const store = createStore(
    reducer,
    initialState,
    hashEnhancer(hashFromState, stateFromStateAndHash)
);

其中hashFromState是hash类型的函数=

它可能是过度的,路由器会更简单,我只是不明白反应路由器或反应路由器redux在所有。

满耀
2023-03-14

您应该侦听hashchange事件,并在其更改后更新状态。要执行双向绑定,还应侦听状态更改,并在状态更改后更新窗口哈希。这就是它的工作原理(小提琴):

function changeHash(state = '', action) {
  if(action.type == 'CHANGE_HASH')
    return action.hash;

  return state;
}

const store = Redux.createStore(changeHash);

store.subscribe(() => {
  const hash = store.getState();
  if (window.location.hash !== hash) {
    window.location.hash = hash;
    console.log('State changed: ' + hash);
  }
});

window.addEventListener("hashchange", () => {
  const hash = window.location.hash;
  if (store.getState() !== hash) {
    store.dispatch({
      type: 'CHANGE_HASH',
      hash
    });
    console.log('Hash changed: ' + hash);
  }
}, false);

setTimeout(() => {
    store.dispatch({
    type: 'CHANGE_HASH',
    hash: '#changed-state'
  });
}, 3000);

setTimeout(() => {
    window.location.hash = '#changed-hash';
}, 6000);
 类似资料:
  • 问题内容: 我们提供了讲座和章节的列表,用户可以在其中选择和取消选择它们。这两个列表存储在redux存储中。现在,我们希望在url的hash标签中保留选定的演讲段和章节段的表示形式,并且对该URL所做的任何更改也应更改存储(双向同步)。 使用react-router甚至react-router- redux 的最佳解决方案是什么? 我们找不到真正的好例子,其中react路由器仅用于维护url的ha

  • 我们有一个讲座和章节的列表,用户可以在其中选择和取消选择它们。这两个列表存储在redux存储中。现在,我们希望在url的哈希标记中保留所选讲座段塞和章节段塞的表示,对url的任何更改也应该更改存储(双向同步)。 什么是最好的解决方案,使用反应路由器或甚至反应路由器redux? 我们真的找不到一些好的例子,其中react路由器只用于维护url的哈希标记,并且只更新一个组件。

  • 我有一个带有搜索面板的网页。搜索面板有几个输入字段:id, size,... 我想要的是当用户设置搜索值(例如:id=123和size=45)并按下搜索按钮时: Redux reducer中的searchState应更新为新的搜索值(id=123,size=45) URL应更改为“http://mydomain/home?id=123 另一方面,如果用户将URL更改为超文本传输协议://myDom

  • Mpx针对表单组件提供了wx:model双向绑定指令,类似于v-model,该指令是一个语法糖指令,监听了组件抛出的输入事件并对绑定的数据进行更新,默认情况下会监听表单组件的input事件,并将event.detail.value中的数据更新到组件的value属性上。 简单实用示例如下: <view> <input type="text" wx:model="{{message}}"> <

  • 双向绑定这个概念在angular出现的时候,就作为王牌概念. 现在几乎是个js前端框架,就有这个功能. 它的概念是: 某个变量, 如果展现在页面上的话: 如果在代码层面进行修改, 那么页面的值就会发生变化 如果在页面进行修改(例如在input标签中), 那么代码的值就会发生变化. 一个演示例子. 在我们的项目中,增加一个 vue页面: src/components/TwoWayBinding.vu

  • 单向绑定非常简单,就是把Model绑定到View,当我们用JavaScript代码更新Model时,View就会自动更新。 有单向绑定,就有双向绑定。如果用户更新了View,Model的数据也自动被更新了,这种情况就是双向绑定。 什么情况下用户可以更新View呢?填写表单就是一个最直接的例子。当用户填写表单时,View的状态就被更新了,如果此时MVVM框架可以自动更新Model的状态,那就相当于我