我正在创建一个带有reactjs、ReactContextAPI、apexChart的仪表板应用程序,其中1000个长度的JSON数据将在7-8个不同的图表上可视化,它包括6-7个变量过滤器。
应用程序结构的基本思想:
两个主要的子组成部分是:
树的示例:
面临的问题:假设Filter组件添加了一个过滤器,它从defaultContext数据中删除一些数据,以便将其同步到chartComponent.
现在,我很困惑,如果我们删除过滤器,我将如何返回数据(之前已经从DefaultContext中删除)。
我有多少更好的方法来解决这个问题?
发布于 2022-08-27 20:57:08
这绝对是一个有效且常见的问题。好消息是,Context
是一个不错的选择。
由于您需要更改数据,上下文必须有一个允许它更改底层数据的接口。
const DataContext = createContext({
data: [], // can have 1000 arrays later
changeData: () => {} // can change the array anytime
})
现在,我们可以用读/写功能包装提供程序。
const DataProvider = ({ children }) => {
const [data, changeData] = useState(initialData)
const value = { data, changeData }
return <DataContext.Provider value={value}>
{children}
</DataContext.Provider>
}
现在,您的应用程序需要在这个上下文提供程序下安装:
const App = () => {
return <DataProvider>...</DataProvider>
}
去消耗它,
const FilterOrChart = () => {
const { data, changeData } = useContext(DataContext)
...
}
在您的Filter
中,您希望调用changeData
,在您的Chart
中,您要访问data
。
老实说,您的案例应该是在线文档中记录的案例,不幸的是,大多数情况下,本教程只讨论读取操作,这实际上不是上下文的重点。阅读上下文几乎就像链式道具,但写作上下文则要强大得多。
发布于 2022-08-28 04:44:01
解决方案就是首先而不是过滤你的真相来源。这意味着不过滤存储在上下文提供程序中的原始状态,而是在下游呈现时将其内联过滤。
状态应该是状态的最小表示形式,不包括派生状态。什么是派生状态?将过滤后的结果看作是从实际状态和派生出来的,这是一些过滤标准。您已经将状态存储在上下文中,因此您现在还需要将筛选存储在状态中(在某个地方,这并不重要)。当您想要“恢复”原始状态时,请清除筛选条件,以便不再过滤数据源。
示例:
在本例中,data
位于筛选它的组件的外部。这是表示“状态”与过滤状态和导出的过滤结果的分离。
const data = [
{
id: "1",
color: "red",
shape: "round"
},
{
id: "2",
color: "green",
shape: "round"
},
{
id: "3",
color: "red",
shape: "square"
},
{
id: "4",
color: "green",
shape: "square"
},
{
id: "5",
color: "blue",
shape: "square"
}
];
function App() {
const [color, setColor] = React.useState("");
const [shape, setShape] = React.useState("");
return (
<div className="App">
<div className="container">
{data
.filter((el) => {
if (color && shape) {
return color === el.color && shape === el.shape;
}
if (color || shape) {
return color === el.color || shape === el.shape;
}
return true;
})
.map((el) => (
<div
key={el.id}
className={clsx("item", {
red: el.color === "red",
green: el.color === "green",
blue: el.color === "blue",
round: el.shape === "round"
})}
>
<p>{el.color}</p>
<p>{el.shape}</p>
</div>
))}
</div>
<div>
<label>
Shape
<select value={shape} onChange={(e) => setShape(e.target.value)}>
<option value="">All</option>
<option value="square">Square</option>
<option value="round">Round</option>
</select>
</label>
<label>
Color
<select value={color} onChange={(e) => setColor(e.target.value)}>
<option value="">All</option>
<option value="red">Red</option>
<option value="green">Green</option>
<option value="blue">Blue</option>
</select>
</label>
<button
type="button"
onClick={() => {
setColor("");
setShape("");
}}
>
Reset
</button>
</div>
</div>
);
}
const rootElement = document.getElementById("root");
const root = ReactDOM.createRoot(rootElement);
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
.App {
font-family: sans-serif;
text-align: center;
}
.container {
display: flex;
gap: 1rem;
padding: 1rem;
justify-content: center;
}
.item {
border: 1px solid;
height: 6rem;
width: 6rem;
}
.round {
border-radius: 50%;
}
.red {
background-color: red;
}
.green {
background-color: green;
}
.blue {
background-color: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/clsx@1.2.1/dist/clsx.min.js"></script>
<div id="root" />
https://stackoverflow.com/questions/73514280
复制相似问题