React(10)React表单元素应用方法大全

x33g5p2x  于2022-03-06 转载在 其他  
字(5.2k)|赞(0)|评价(0)|浏览(295)

16、表单

总结写前面

  1. 值的改变,通过 onChange 事件触发(包括文字输入框、radio、checkbox);
  2. 选中与否,通过设置 HTML 元素的 checked 等于一个符合要求的 state 的值(因此表达式结果为 true,于是 checked='true' 就是选中),来实现。

【form】标签:

如果用 form 标签的话,在通过 submit 按钮提交时,会自动触发页面跳转,但这个通常是我们不需要的;

解决办法是,添加 onSubmit 事件,如:<form onSubmit={this.submit}>,在这个函数里,通过 e.preventDefault() 阻止默认的提交行为,

示例代码:

class HelloWord extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            name: ''
        }
        this.submit = this.submit.bind(this)
    }

    render() {
        return <form onSubmit={this.submit}>
            <label>
                male
                <input type="radio" name='gender' value='male'/>
            </label>
            <label>
                female
                <input type="radio" name='gender' value='female'/>
            </label>
            <input type="submit"/>
        </form>
    }

    submit(e) {
        console.log(arguments)
        e.preventDefault();
    }
}

input[type=text]】标签:

默认情况下,通过 value=this.state.xxx 绑定,是单向绑定。即改变 state 存储的值,可以自动修改 input 的值,但是用户修改 input 的值,是无法修改成功的。

用户想要输入值,必须设置 onChange 事件才可以,这样才能实现 双向绑定

示例代码:

class HelloWord extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            value: ''
        }
        this.valueChange = this.valueChange.bind(this)
    }

    render() {
        return <form onSubmit={this.submit}>
            <input type="text" value={this.state.value} onChange={this.valueChange}/>
            <br/>
            输入框的值:{this.state.value}
        </form>
    }

    valueChange(e) {
        this.setState({
            value: e.target.value
        })
    }
}

textarea】标签:

使用方法等同 input[type=text],略。

input[type=radio]】标签:

注意,radio 以及 checkbox 的 value 设置和一般不同。

原因在于,radio 的 value 属性,表示当你选中这个单选框时,这个单选框的值,当你需要表示我选中这个单选框,那么应该通过 checked = true|'check' 来实现选中。

示例代码:

class HelloWord extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            gender: 'male'
        }
        this.select = this.select.bind(this)
    }

    render() {
        return <form>
            <label>
                male
                {/* 可以返回 true 表示选中 */}
                <input type="radio" name='gender' value='male'
                       checked={this.state.gender === 'male'}
                       onChange={this.select}/>
            </label>
            <label>
                female
                {/* 也可以返回checked 表示选中 */}
                <input type="radio" name='gender' value='female'
                       checked={this.state.gender === 'female' ? 'checked' : ''}
                       onChange={this.select}/>
            </label>
            <br/>
            你当前选择的性别是:{this.state.gender}
        </form>
    }

    select(e) {
        this.setState({
            gender: e.target.value
        })
    }
}

input[type=checkbox]】标签:

这个显然就更麻烦了。他表现 选中/未选中 状态,和 radio 是一样的。

但问题在于,checkbox 在一个 name 属性下可能有多个变量,

所以你需要用数组来存储当前选中的 checkbox 有谁,

例如:gender: ['male', 'female']

然后通过 indexOf(xx) > -1 来判断存在不存在(-1 表示不存在)。

示例代码:

class HelloWord extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            gender: ['male', 'female']
        }
        this.select = this.select.bind(this)
    }

    render() {
        return <form>
            <label>
                male
                {/* 可以返回 true 表示选中 */}
                <input type="checkbox" name='gender' value='male'
                       checked={this.state.gender.indexOf('male') > -1}
                       onChange={this.select}/>
            </label>
            <label>
                female
                {/* 也可以返回checked 表示选中 */}
                <input type="checkbox" name='gender' value='female'
                       checked={this.state.gender.indexOf('female') > -1}
                       onChange={this.select}/>
            </label>
            <br/>
            你当前选择的性别是:{this.state.gender.join(',')}
        </form>
    }

    select(e) {
        // 先拿到值和索引
        let v = e.target.value
        let i = this.state.gender.indexOf(v)
        // 有则移除,无则添加
        if (i === -1) {
            this.state.gender.push(v)
        } else {
            this.state.gender.splice(i, 1)
        }
        // 最后必须setState设置一下,才会触发render
        this.setState({
            gender: this.state.gender
        })
    }
}

当然,也可以通过 对象 的方式来存储,写的话更简单,只不过取用数据的时候,可能会麻烦一些,如示例:

class HelloWord extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            gender: {
                male: false,
                female: false
            }
        }
        this.select = this.select.bind(this)
    }

    render() {
        return <form>
            <label>
                male
                <input type="checkbox" name='gender' value='male'
                       checked={this.state.gender.male}
                       onChange={this.select}/>
            </label>
            <label>
                female
                <input type="checkbox" name='gender' value='female'
                       checked={this.state.gender.female}
                       onChange={this.select}/>
            </label>
            <br/>
            你当前选择的性别是:{JSON.stringify(this.state.gender)}
        </form>
    }

    // 以下这种写法是可复用写法(即多个不同的 checkbox 可以复用这一个函数)
    select(e) {
        let v = e.target.value
        let name = e.target.name
        this.state[name][v] = !this.state[name][v]
        this.setState({
            [name]: this.state[name]
        })
    }
}

【select】标签:

select 标签在使用的时候,和 Vue 有一点最大的不同之处在于:

  1. 当 Vue 中设置 select 标签的值为 空字符串 时,那么 select 标签会不选中任何 option;
  2. 当 React 中设置 select 标签的值为 空字符串3 时,那么 select 标签会默认选中 第一个 option 标签
  3. 不管将 select 标签绑定的 value 的值设置为 空字符串 ,或者是 null,或者是 option 标签不存在的值,React 都会将 select 标签绑定的 value 的值设置为 空字符串
  4. 然后由于当 select 标签绑定的值为空字符串时,会在 页面视觉 上,默认选中第一个 option 标签;
  5. 如果你此时去拿select的值,拿到的是空字符串;但是通过select标签来拿值,那么拿到的是第一个 option 的值;

也就是说,当值为 空字符串 时,页面上显示的效果,和实际值不同!

所以需要通过 js 手动将该 DOM 标签的值设置为空字符串,才可以。

具体解决办法如下(包含 select 标签使用方法):

class HelloWord extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            gender: ''
        }
        this.select = this.select.bind(this)
    }

    render() {
        return <div>
            <select value={this.state.gender} ref={input => {
                this.DOM = input
            }} onChange={this.select} id='abc'>
                <option value="male">male</option>
                <option value="female">female</option>
            </select>
            <br/>
            你当前选择的性别是:{this.state.gender}
            <button onClick={this.setGender.bind(this)}>点击不设置gender</button>
        </div>
    }

    // 以下这种写法是通用写法
    select(e) {
        let v = e.target.value
        this.setState({
            gender: v
        })
    }

    setGender() {
        this.setState({
            gender: ''
        })
    }

    // 如果假如 select 为空的话,需要通过 ref 手动拿到元素,然后设置 value 的值为空,从而默认不选择值
    componentDidUpdate(preProps, preState) {
        console.log('componentDidUpdate', arguments)
        if (this.state.gender === '') {
            this.DOM.value = ''
        }
    }

    // 如果初始为空的话,也需要在这里手动配置一波,这是组件创建时【生命周期】在挂载完毕时执行的函数
    componentDidMount() {
        console.log('componentDidMount')
        if (this.state.gender === '') {
            this.DOM.value = ''
        }
    }
}

相关文章