跳到主要内容

React 动态添加输入表单/动态添加ref并传出

· 阅读需 4 分钟
Meoo

开发过程中经常需要封装组件,如果多个功能需求都差不太多,一个组件可以复用的话,那简直太方便了。

举个例子,一个输入表单的组件,复用时每一个不同的功能里,输入标签数量是不一样的,比如登录有两个输入框,而修改用户名密码可能有4个输入框。指定几个输入框以及提示、内容什么的可以通过props传入。重点是如何获取这几个输入标签的值并传给父组件呢?当然,一种方式是使用受控组件,每一个输入框对应一个state或者他们的值都传入到一个存数组的state里。另一种方式通过非受控组件实现,也就是这里要说的。

App.js

function App({ getValues }) {
const refs = [] // 用于储存每一个 <h3> 对应的 DOM,这里用h标签代替input是为了使效果更加直观
const data = [1, 2, 3, 4, 5] // 可以由 props 传入,自己指定

return (
<div>
{data.map((value, index) => {
// 如果 ref 回调函数是以内联函数的方式定义的,在更新过程中它会被执行两次
// 第一次传入参数 null,然后第二次会传入参数 DOM 元素,所以加个判断再 push
return <h3 ref={(r) => { if (r) refs.push(r) }} key={index}>{value}</h3>
})}
// 点击确认,将 refs 数组传递给父组件,就可以在父组件通过该元素获得值
<button onClick={() => { getValues(refs) }}>确认</button>
</div>
);
}

export default App;

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

// 把该函数传给子组件,用来在子组件里传来refs数组
function passMeValues(values) {
console.log(values)
}

ReactDOM.render(
<App getValues={passMeValues} />,
document.getElementById('root')
);

页面:

在这里插入图片描述

重要的都写在了注释中,点击确认按钮,这些标签组成的数组就打印出来了(内容太长截图不到,只截了把属性收起的图),控制台输出如下:

在这里插入图片描述

流程:子组件声明一个空数组用于储存DOM元素,渲染输入标签时在它的ref属性中传入回调函数,将函数传入的ref给push到数组里,提交表单时,执行父组件通过props传来的函数,把数组传进去,于是就完成了子组件的不定数量输入标签DOM传递给父组件。就可以从父组件遍历DOM数组,通过value属性获取他们的值了。在封装一个可复用性强的组件时,非常有用。