gpt4 book ai didi

javascript - 将 redux 存储传递给 react-dom/server renderToString() 方法

转载 作者:行者123 更新时间:2023-12-03 06:55:03 25 4
gpt4 key购买 nike

我有一个常规的 React 应用程序 (CRA)。在应用程序的一部分中,我使用 Mapbox 来显示 map ,并且要呈现弹出窗口,我需要传入要呈现的 html 内容字符串。我仍然想使用 React 来呈现弹出窗口,而不是传入原始 html,所以我这样做:

const renderedContent = renderToString(
<Popup
port={port}
poiType={poiType}
activeView={activeView}
isPortsOnly={isPortsOnly}
locations={locations}
/>
)
从渲染弹出组件中获取 html 字符串。这仍然是客户端,文档说可以使用 renderToString()对于客户端的这些用例也是如此。
new Popup()
.setLngLat(coordinates)
.setHTML(renderedContent)
.addTo(self.map)
使用 html 字符串创建一个弹出窗口。

这按预期工作。 现在我的问题是:我不想在我的 Popup 组件中使用 redux。两者都调度一个事件,并读取全局状态。我怎样才能做到这一点?我真的可以这样做吗?

我试过的
如果我尝试只使用 redux在 Popup 组件中,我收到以下错误消息: Error: could not find react-redux context value; please ensure the component is wrapped in a <Provider>

最佳答案

嗯,这很有趣!我做了一个sandbox使用以下代码,滚动查看一些解释:
Popup.js

import React, { useRef, useEffect } from "react";
import { connect } from "react-redux";
import { Popup } from "mapbox-gl";

import { zoomAction } from "./ActionCreators";

const CustomPopup = ({ zoomAction, lng, lat, zoom, map }) => {
const popUpRef = useRef(null);

useEffect(() => {
if (popUpRef.current && map) new Popup().setLngLat([lng, lat]).setDOMContent(popUpRef.current).addTo(map);
}, [popUpRef, map, lng, lat]);

const zoomIn = () => {
zoomAction();
map.zoomIn(zoom);
};

return (
<div ref={popUpRef}>
<h1>Hello World!</h1>
<button onClick={zoomIn}>zoom in (currently {zoom})</button>
</div>
);
};

const mapStateToProps = (state) => {
return { ...state };
};

const mapDispatchToProps = { zoomAction };

export default connect(mapStateToProps, mapDispatchToProps)(CustomPopup);
MapGl.js
import React, { useMemo, useState } from "react";
import MapboxGl from "mapbox-gl";
import { connect } from "react-redux";

import "mapbox-gl/dist/mapbox-gl.css";
import "./MapGl.css";

import Popup from "./Popup";

MapboxGl.accessToken = "pk.eyJ1IjoibmljZXk3MjMxMSIsImEiOiJja2hrdGE4MHkwMGxxMndteDRucGIyMDVqIn0.MKokCfCrE8VskLRUNGO0hw";

const MapGl = ({ zoom, lng, lat }) => {
const [isLoaded, setIsLoaded] = useState(false);
const map = useMemo(() => {
if (isLoaded)
return new MapboxGl.Map({
container: document.querySelector(".mapContainer"),
style: "mapbox://styles/mapbox/streets-v11",
center: [lng, lat],
zoom: zoom
});
}, [isLoaded]);

return (
<div>
<div ref={() => setIsLoaded(true)} className="mapContainer" />
{map && <Popup map={map} />}
</div>
);
};

const mapStateToProps = (state) => {
return { ...state };
};

export default connect(mapStateToProps)(MapGl);
MapGl.css
.mapContainer {
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
}
应用.js
import React from "react";

import "./App.css";

import MapGl from "./MapGl";

export default () => {
return <MapGl />;
};
索引.js
import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";

import "./index.css";

import store from "./Store";
import App from "./App";

ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root")
);
Store.js
import { createStore } from "redux";

const initialState = {
lng: -96,
lat: 37.8,
zoom: 3
};

function rootReducer(state = initialState, action) {
switch (action.type) {
case "zoom":
return { ...state, zoom: state.zoom + 1 };
default:
return state;
}
}

let store = createStore(rootReducer);

export default store;
ActionCreators.js
export const zoomAction = () => ({
type: "zoom"
});
首先是更换 setHtmlsetDOMContent它采用现有的 DOM 节点而不是字符串。其次使用 renderToString与情境化的服务器端渲染相关联。在此示例中,我使用一个按钮创建一个弹出窗口,该按钮调度缩放操作以更新商店以及同步 map 对象本身。您可以看到应用于 map 的新缩放值以及在弹出窗口内更新的存储值。

关于javascript - 将 redux 存储传递给 react-dom/server renderToString() 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64766189/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com