类型 (Type)
1. 受控组件 (controlled component)
值将会同步到state, 并且使用value属性
1) textarea onChange=handleChange(event: ChangeEvent<HTMLTextAreaElement>)
event.target.value
2) input onChange=handleChange(event: ChangeEvent<HTMLInputElement>)
event.target.value
3) select onChange=handleChange(event: ChangeEvent<HTMLSelectElement>)
2. 非受控组件 (non-controlled component)
值不会同步到state, 使用defaultValue属性
设计受控组件 (Design controlled component)
每次设计受控组件的时候,要记得放两个属性
1) value={xxx}, onChange={xxx}
We could use hidden input to submit some data
<input type="hidden">
搜索 (Searching & Pagination)
http://xxx/xxx/xx?keyword=xx&page=n
Since after refreshing, content will be lost
Approach to redirect to url with parameters:
Approach to retrieve url: xxx/xxx?keyword=xx
Third-party Hooks to set initial form values
and should bind this form with original form:
Third-party Hooks to get all form values
Third-party form validation tool:
1) React-Hook-Form
2) Formik
Checkbox
在antd的Form表单中,<Input />组件都是有value属性的, <Checkbox></Checkbox>没有,如何解决?
可以使用valuepropName="checked",来表示 checked代替value属性,放在Form.Item中
e.g.,
在提交表单的时候,checkbox有多个选项,如何设置name?
可以使用useState来定义一个selectedValues,每次选中/取消选中 的时候(onChange), 判断当前的checkbox是否在selectedValues里面,如果在,就删除,如果不在,就加入。然后设置checkbox的checked={selecetedValues.includes(value)}
然后使用一个<input type="hidden" value={selectedValues.toString()} /> 隐藏域来提交。
在解决的过程中,我遇到了一个问题: 就是我准备在初始化的时候,将所有默认选中的checkbox选中,我使用了以下的useEffect函数
useEffect(() => { list.forEach(eachItem => { const { value, checked } = eachItem; if (checked) { setSelectedValues(selectedValues.concat(value)); } }) }, [list, selectedValues])
但是这造成了无限循环。因为中途设置了selectedValues数组,然后设置了这个数组的同时又触发了useEffect函数。
可以改成下面的格式: 函数式更新
什么是函数式更新?
函数式更新就是下面的形式:
setNum(num => num + 1);
会获取最新的state。
在React里面,React会认为对于state的操作是非常频繁的,所以会把很多次的setState合并成一次。那么如果多次调用
const [num, setNum] = useState(1);
setNum(num + 1);
setNum(num + 1);
只会在最初的num上面加一。结果为2
但是如果使用函数式更新的话,可以获取到最新的state
const [num, setNum] = useState(1);
setNum(num => num + 1);
setNum(num => num + 1);
结果为3
Paragraph
在项目中,有Paragraph组件,但是发现 换行的效果不会显示。有三种解决方案。
1) 可以使用dangerouslySetInnerHTML来设置 才能实现换行效果
首先必须在需要换行的地方 之前是"\n",现在改为<br>
然后使用如下格式:
但是这样很危险,因为别人可以插入
2) 使用split拆分,然后分行渲染
textList.map((c, i) => {
<span>
{i == 0 && {<br />}}
{text}
</span>
})
但是这样的话 空格无法显示 写多了会被吞并
3) 直接使用style={{ whiteSpace: "pre-wrap"}} 遇到<br>或者\n会自动换行且不吞并空格
whiteSpace属性有五个选项
- normal: 连续的空白符会被合并,换行符会被当作空白符来处理,填充line boxes 行框盒子时是必要
- nowrap: 连续的空白符会被合并,但是文本内的换行符无效
- pre: 连续的空白符会被保留,在遇到换行符或者<br>元素时才会换行
- pre-wrap: 连续的空白符会被保留,在遇到换行符或者<br>,或者需要为了填充(line boxes)行框盒子时才会换行
- pre-line: 连续的空白符会被合并,在遇到换行或者<br>元素,或者需要为了填充行框盒子时会换行
- break-space: 与pre-wrap行为相同,除了行尾会换行
Comments
Post a Comment