我有一个表单,其中用户创建了一个编码问题。在表单中,可以通过输入和输出文本框添加示例测试用例。用户可以单击按钮添加新的测试用例。现在我有一个state对象,它保存所有表单数据formObj,其中有一个示例_test_cases字段,我想保存一个对象数组,比如:[{input:,output::}]。
我遇到的问题是更新此阵列。我需要能够在每次添加测试用例时将一个新对象连接到它。然后在文本框更改时更新该索引处的状态。我尝试创建一个无状态数组并对其进行更新,然后将sample\u test\u案例设置到该数组中。然而,这是行不通的。
这是一个沙盒,上面有我的代码:https://codesandbox.io/s/eloquent-snowflake-n4bpl?file=/src/AddProblemForm.js
如果有人能给我一些有用的建议。我不太熟悉Javascript或复杂的状态管理。谢谢
我建议您在状态复杂的情况下使用useReducer钩子。
钩子API
当您有涉及多个子值的复杂状态逻辑时,或者当下一个状态依赖于前一个状态时,useReucer通常比useState更可取。
addProblemForm.js:
import React, { useReducer } from "react";
import { Form, Button, Col } from "react-bootstrap";
import { BsPlusSquare } from "react-icons/bs";
import SampleTestCase from "./SampleTestCase";
const initialState = {
sample_test_cases: [],
counter: 0
// other state obj info
};
function reducer(state, action) {
switch (action.type) {
case "addSampleTestCase": {
const { data } = action;
return {
...state,
sample_test_cases: [...state.sample_test_cases, data],
counter: state.counter + 1
};
}
case "updateTest": {
const { index, value } = action;
return {
...state,
sample_test_cases: state.sample_test_cases.map((item, i) => {
if (i === index) {
return value;
} else {
return item;
}
})
};
}
default:
throw new Error();
}
}
const AddProblemForm = () => {
const [state, dispatch] = useReducer(reducer, initialState);
const AddSampleTestCase = () => {
dispatch({ type: "addSampleTestCase", data: { input: "", output: "" } });
};
/* console.log(state); */
return (
<div>
Problem Form
<Form>
<h5 style={{ paddingTop: "1rem" }}>Sample Test Cases</h5>
{state.sample_test_cases.map((sample_test_case, i) => (
<div key={i}>
<SampleTestCase
sample_test_case={sample_test_case}
updateValue={(value) =>
dispatch({ type: "updateTest", index: i, value })
}
/>
<hr />
</div>
))}
<Button onClick={AddSampleTestCase}>
<div>Add Sample Test Case</div>
</Button>
</Form>
</div>
);
};
export default AddProblemForm;
SampleTestCase.js:
import React from "react";
import { Form, Button, Col } from "react-bootstrap";
const SampleTestCase = ({ sample_test_case, updateValue }) => {
return (
<Form.Row>
<Col>
<Form.Group controlId="input">
<Form.Label>Sample Input</Form.Label>
<Form.Control
required
as="textarea"
rows={2}
value={sample_test_case.input}
onChange={(event) => updateValue(event.target.value)}
/>
</Form.Group>
</Col>
<Col>
<Form.Group controlId="output">
<Form.Label>Sample Output</Form.Label>
<Form.Control
required
as="textarea"
rows={2}
value={sample_test_case.output}
onChange={(event) => updateValue(event.target.value)}
/>
</Form.Group>
</Col>
</Form.Row>
);
};
export default SampleTestCase;
请参阅下面的片段(我在保存沙箱时遇到问题)。它解决的几个问题:
arr
变量跟踪状态;更新不会触发重新渲染,因此您需要修改formObj
状态中的sample\u test\u cases
数组。值
也应该反映您的状态。为了方便起见,我将测试用例作为道具传递到SampleTestCase
组件中,因此它将对状态更改做出反应。示例测试案例
数组将状态设置为新对象,该数组由第一个i-1测试案例、修改输入的第i个新测试案例以及其余测试案例构成。SampleTestCase
移到AddProblemForm
组件之外。如果你不这样做,你会发现每当输入文本区域被改变时,你就会失去键盘的焦点。这是因为将在每个渲染上重新定义SampleTestCase
组件,该组件由状态更改触发。(类似的问题:React.js-重新提交时输入失去焦点)import React, { useState } from "react";
import { Form, Button, Col } from "react-bootstrap";
import { BsPlusSquare } from "react-icons/bs";
const SampleTestCase = ({ testCase, updateInput }) => {
return (
<Form.Row>
<Col>
<Form.Group controlId="input">
<Form.Label>Sample Input</Form.Label>
<Form.Control
required
as="textarea"
rows={2}
onChange={updateInput}
value={testCase.input}
/>
</Form.Group>
</Col>
<Col>
<Form.Group controlId="output">
<Form.Label>Sample Output</Form.Label>
<Form.Control
required
as="textarea"
rows={2}
// onChange={(event) =>
// setFormObj({
// ...formObj,
// sample_test_cases: {
// ...formObj.sample_test_cases,
// output: event.target.value
// }
// })
// }
/>
</Form.Group>
</Col>
</Form.Row>
);
};
const AddProblemForm = () => {
const [formObj, setFormObj] = useState({
sample_test_cases: [{ input: "", output: "" }]
// other state obj info
});
const AddSampleTestCase = () => {
// make new instance!
const newTestCase = { input: "", output: "" };
setFormObj({
...formObj,
sample_test_cases: [...formObj.sample_test_cases, newTestCase]
});
};
console.log(formObj);
const updateInputFor = (i) => (event) => {
event.preventDefault();
const { sample_test_cases } = formObj;
const testCase = sample_test_cases[i];
testCase.input = event.target.value;
setFormObj({
...formObj,
sample_test_cases: [
...sample_test_cases.slice(0, i),
testCase,
...sample_test_cases.slice(i + 1)
]
});
};
return (
<div>
Problem Form
<Form>
<h5 style={{ paddingTop: "1rem" }}>Sample Test Cases</h5>
{formObj.sample_test_cases.map((testCase, i) => (
<React.Fragment key={i}>
<SampleTestCase
key={i}
testCase={testCase}
updateInput={updateInputFor(i)}
/>
<hr />
</React.Fragment>
))}
<Button onClick={AddSampleTestCase}>
<div>Add Sample Test Case</div>
</Button>
</Form>
</div>
);
};
export default AddProblemForm;
我有一个问题与primeface数据表。我有一个数据与一些条目和一个列与一个按钮内。如果按钮被按下,一个弹出窗口打开与另一个数据表。第二个数据表中的条目取决于行中的按钮被按下。 Bean2 问题是弹出式数据表中没有列出任何条目,尽管在db查询之后的列表中有一些条目。 有没有办法修复这个bug?提前感谢! 更新1:
我们使用liquibase对数据库进行源代码控制。最初,我们从Postgres开始,创建了数据类型为特定于Postgres的列的变更集。 例如,我们有一个变更集,它创建了具有“JSON”类型字段的表。现在,我们想转移到其他数据库。因此,当我们针对另一个数据库运行变更集时,它无法创建表。我尝试添加“failOnError=false”。但是,后面的变更集失败,因为该表不存在。 您能建议如何重构旧的变
Flarum 正处于测试阶段,有关如何更新的说明将在每次 版本发布公告中公示。
如果你想和社区以及开发版的 Requests 保持最新的联系, 这有几种方式: GitHub 最好的方式是追踪 Requests 开发版本的 GitHub 库. Twitter 我经常推送关于 Requests 的新功能和新版本. 关注 @kennethreitz 即可获得更新。 Release History dev Improvements Bugfixes 2.18.1 (2017-06-1
和模型新增一样,更新操作同样也会经过修改器、自动完成以及模型事件等处理,并不等同于数据库的数据更新,而且更新方法和新增方法使用的是同一个方法,通常系统会自动判断需要新增还是更新数据。 查找并更新 在取出数据后,更改字段内容后使用save方法更新数据。这种方式是最佳的更新方式。 $user = User::get(1); $user->name = 'thinkphp'; $user->em
Yearning采用自动表结构同步 无需手动更新表结构。只需停止原服务并替换安装包后重新启动即可 在一些特殊的升级情况中(破坏性变更)需要手动进行数据同步操作.如在版本更新公告中并无提示破坏性升级则无视以下命令! ./Yearning migrate