- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试创建一个动态表单,其中表单输入字段是根据 API 返回的数据呈现的。
由于 atom 需要有一个唯一的键,我尝试将它包装在一个函数中,但每次我更新字段值或组件重新安装(尝试更改选项卡)时,我都会收到一条警告:
我在这里做了一个小的运行例子https://codesandbox.io/s/zealous-night-e0h4jt?file=/src/App.tsx (与下面相同的代码):
import React, { useEffect, useState } from "react";
import { atom, RecoilRoot, useRecoilState } from "recoil";
import "./styles.css";
const textState = (key: string, defaultValue: string = "") =>
atom({
key,
default: defaultValue
});
const TextInput = ({ id, defaultValue }: any) => {
const [text, setText] = useRecoilState(textState(id, defaultValue));
const onChange = (event: any) => {
setText(event.target.value);
};
useEffect(() => {
return () => console.log("TextInput unmount");
}, []);
return (
<div>
<input type="text" value={text} onChange={onChange} />
<br />
Echo: {text}
</div>
);
};
export default function App() {
const [tabIndex, setTabIndex] = useState(0);
// This would normally be a fetch request made by graphql or inside useEffect
const fields = [
{ id: "foo", type: "text", value: "bar" },
{ id: "hello", type: "text", value: "world" }
];
return (
<div className="App">
<RecoilRoot>
<form>
<button type="button" onClick={() => setTabIndex(0)}>
Tab 1
</button>
<button type="button" onClick={() => setTabIndex(1)}>
Tab 2
</button>
{tabIndex === 0 ? (
<div>
<h1>Fields</h1>
{fields.map((field) => {
if (field.type === "text") {
return (
<TextInput
key={field.id}
id={field.id}
defaultValue={field.value}
/>
);
}
})}
</div>
) : (
<div>
<h1>Tab 2</h1>Just checking if state is persisted when TextInput
is unmounted
</div>
)}
</form>
</RecoilRoot>
</div>
);
}
这甚至可以通过后坐力实现。我的意思是它似乎有效,但我不能忽略警告。
最佳答案
This answer展示了如何使用记忆化手动管理原子的多个实例。
但是,如果您的每个使用实例的defaultValue
都不会改变,那么 Recoil 已经提供了一个可以为您处理创建和内存的实用程序:atomFamily
.我将从上一个链接中引用一些相关信息(但请阅读所有内容以充分理解):
... You could implement this yourself via a memoization pattern. But, Recoil provides this pattern for you with the
atomFamily
utility. An Atom Family represents a collection of atoms. When you callatomFamily
it will return a function which provides theRecoilState
atom based on the parameters you pass in.The
atomFamily
essentially provides a map from the parameter to an atom. You only need to provide a single key for theatomFamily
and it will generate a unique key for each underlying atom. These atom keys can be used for persistence, and so must be stable across application executions. The parameters may also be generated at different callsites and we want equivalent parameters to use the same underlying atom. Therefore, value-equality is used instead of reference-equality foratomFamily
parameters. This imposes restrictions on the types which can be used for the parameter.atomFamily
accepts primitive types, or arrays or objects which can contain arrays, objects, or primitive types.
这是一个工作示例,展示了在使用 的实例时如何使用
每个输入的状态:id
和 defaultValue
(作为元组的值的唯一组合)作为参数>atomFamily
body { font-family: sans-serif; }
input[type="text"] { font-size: 1rem; padding: 0.5rem; }
<div id="root"></div><script src="https://unpkg.com/react@17.0.2/umd/react.development.js"></script><script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js"></script><script src="https://unpkg.com/recoil@0.6.1/umd/recoil.min.js"></script><script src="https://unpkg.com/@babel/standalone@7.17.7/babel.min.js"></script><script>Babel.registerPreset('tsx', {presets: [[Babel.availablePresets['typescript'], {allExtensions: true, isTSX: true}]]});</script>
<script type="text/babel" data-type="module" data-presets="tsx,react">
// import ReactDOM from 'react-dom';
// import type {ReactElement} from 'react';
// import {atomFamily, RecoilRoot, useRecoilState} from 'recoil';
// This Stack Overflow snippet demo uses UMD modules instead of the above import statments
const {atomFamily, RecoilRoot, useRecoilState} = Recoil;
const textInputState = atomFamily<string, [id: string, defaultValue?: string]>({
key: 'textInput',
default: ([, defaultValue]) => defaultValue ?? '',
});
type TextInputProps = {
id: string;
defaultValue?: string;
};
function TextInput ({defaultValue = '', id}: TextInputProps): ReactElement {
const [value, setValue] = useRecoilState(textInputState([id, defaultValue]));
return (
<div>
<input
type="text"
onChange={ev => setValue(ev.target.value)}
placeholder={defaultValue}
{...{value}}
/>
</div>
);
}
function App (): ReactElement {
const fields = [
{ id: 'foo', type: 'text', value: 'bar' },
{ id: 'hello', type: 'text', value: 'world' },
];
return (
<RecoilRoot>
<h1>Custom defaults using atomFamily</h1>
{fields.map(({id, value: defaultValue}) => (
<TextInput key={id} {...{defaultValue, id}} />
))}
</RecoilRoot>
);
}
ReactDOM.render(<App />, document.getElementById('root'));
</script>
关于reactjs - Recoil 中的动态原子键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71527067/
我正在尝试创建一个动态表单,其中表单输入字段是根据 API 返回的数据呈现的。 由于 atom 需要有一个唯一的键,我尝试将它包装在一个函数中,但每次我更新字段值或组件重新安装(尝试更改选项卡)时,我
我正在尝试创建一个动态表单,其中表单输入字段是根据 API 返回的数据呈现的。 由于 atom 需要有一个唯一的键,我尝试将它包装在一个函数中,但每次我更新字段值或组件重新安装(尝试更改选项卡)时,我
我可以将 Recoil 原子的默认值设置为对象吗? 例如。: export const currentUserState = atom({ key: 'currentUserState', d
我正在测试 Recoil,我需要管理要在主页上显示的帖子列表。 我的第一个想法是把所有的帖子都做成一个大原子,但这似乎有点暴力,因为我们可以直接在首页上编辑帖子。 我的第二个想法是动态生成带有前缀的原
我正在我目前正在构建的 React 框架中试验 Recoil。在我的用例中,应用程序将根据用户事件生成一个操作对象,然后将其发送到服务器,从服务器获取应用程序状态。 Action 存储在反冲 atom
根据文档, https://recoiljs.org/docs/api-reference/core/RecoilRoot 接受 Prop 为 initializeState?: (MutableSn
我刚开始在一个新项目中使用 Recoil,我不确定是否有更好的方法来完成它。 我的应用程序是一个基本编辑包含对象数组的 JSON 文件的界面。它读入文件,根据特定属性将对象分组到选项卡中,然后用户可以
根据文档, https://recoiljs.org/docs/api-reference/core/RecoilRoot 接受 Prop 为 initializeState?: (MutableSn
我刚开始在一个新项目中使用 Recoil,我不确定是否有更好的方法来完成它。 我的应用程序是一个基本编辑包含对象数组的 JSON 文件的界面。它读入文件,根据特定属性将对象分组到选项卡中,然后用户可以
我正在尝试了解 React Recoil 以及更新后的原子值何时可用,或者如何使新值在应用程序中垂直和水平传播。 例如,如果我有一个名为 userState 的原子,并且我更新了它的一个属性,如 av
我正在尝试了解 React Recoil 以及更新后的原子值何时可用,或者如何使新值在应用程序中垂直和水平传播。 例如,如果我有一个名为 userState 的原子,并且我更新了它的一个属性,如 av
我正在使用 Recoil,我想从实用程序函数内访问组件外部的存储(获取/设置)。 更一般地说,人们如何编写可重用函数来使用 Recoil 操纵全局状态?使用 Redux,我们可以直接将事件分派(dis
现状 我正在使用 Recoil在 React 中管理状态应用。我正在使用 Atom Effects使用 API 备份反冲值。 当我的 Atom 检测到身份验证 token 有问题时,我希望它以某种方式
我正在尝试将 RecoilJS 中原子的默认值设置为异步 API 调用的值。我这样做是为了当某个 React 组件呈现时,它将拥有数据库中的所有当前集合,而无需调用 useEffect()。这是我的代
我是 Recoil.js 的新手,我在应用程序中为登录用户提供了以下原子和选择器: const signedInUserAtom = atom({ key: 'signedInUserAtom
我正在运行一些 react-testing-library 测试并收到警告 Did not retain recoil value on render, or committed after time
我得到的错误是,无法删除[对象数组]类型的属性“%1”错误:无法在ObserverProxy处删除[对象数组]的属性“%1”。取消订阅(http://localhost:3000/static/js/
我是一名优秀的程序员,十分优秀!