简体   繁体   中英

Disabling React components with radio buttons using Material-UI

I'm quite new to ReactJS and Material-UI. Only working for roughly 3 weeks with those. The problem I'm struggling with right now is: -I have 2 radio buttons in a group and 2 components (text field and select field); -I want to disable the textField when the first radio button is checked while the selectField is still active; -When the 2nd radio button is checked the textField should be enabled and the selectField should be enabled;

Thank you in advance for any help you can provide! :) I have the following:

The radio buttons component

 import React, {Component} from 'react'; import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; import {RadioButton, RadioButtonGroup} from 'material-ui/RadioButton'; const styles = { block: { maxWidth: 30, }, radioButton: { marginBottom: 16, maxWidth: 10, }, }; export let disable1=false; export let disable2=false; class RadioBtn extends Component { render() { function change() { if (RadioButtonGroup.valueSelected === "0") { disable2 = true; disable1 = false; return disable1; } else if (RadioButtonGroup.valueSelected === "1") { disable1 = true; disable2 = false; return disable2; } } return ( <MuiThemeProvider> <div> <RadioButtonGroup name="search" defaultSelected="0" onChange={change()} > <RadioButton value="0" style={styles.radioButton} name="users" className="users" /> <RadioButton value="1" style={styles.radioButton} name="team" className="team" /> </RadioButtonGroup> </div> </MuiThemeProvider> ) } } export default RadioBtn; 

The selectField component

 import React, {Component} from 'react'; import SelectField from 'material-ui/SelectField'; import MenuItem from 'material-ui/MenuItem'; import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; import getMuiTheme from 'material-ui/styles/getMuiTheme'; import './Team.css'; import {disable2} from '../radioButton/RadioBtn'; const muiTheme3 = getMuiTheme({ palette: { color: 'fff', primary1Color: '#005FA8', accent1Color: '#fff', accent3Color: '#005FA8', textColor: '#000', alternateTextColor: '#005FA8', hintColor: '#ff0000', labelColor: '#000', floatingLabelText: '#000', }, tableHeaderColumn: { textColor: '#000', height: 56, spacing: 24, }, textField: { color: '#000', }, menu: { backgroundColor: '#005FA8', containerBackgroundColor: '#005FA8', borderColor: '#005FA8', }, table: { backgroundColor: '#005FA8', borderColor: '#005FA6', }, icon: { color: '#000', }, }); const styles = { customWidth: { width: 500, }, }; class Team extends Component { state = { value: 1, }; handleChange = (event, index, value) => this.setState({value}); render() { return ( <MuiThemeProvider muiTheme={muiTheme3}> <div id="div-color"> <SelectField // floatingLabelText="Team" floatingLabelStyle={{color: '#000', fontSize: 20}} menuItemStyle={{backgroundColor: '#005FA8'}} listStyle={{backgroundColor: '#005FA8', containerBackgroundColor: '#005FA8'}} underlineStyle={{borderColor: '#000'}} maxHeight={300} value={this.state.value} onChange={this.handleChange} style={styles} disabled={disable2} > <MenuItem value={1} selected disabled primaryText="Select a team" /> <MenuItem value={2} primaryText="Team1" /> <MenuItem value={3} primaryText="Team2" /> <MenuItem value={4} primaryText="Team3" /> <MenuItem value={5} primaryText="Team4" /> <MenuItem value={6} primaryText="Team5" /> <MenuItem value={7} primaryText="Team6" /> <MenuItem value={8} primaryText="Team7" /> <MenuItem value={9} primaryText="Team8" /> <MenuItem value={10} primaryText="Team9" /> <MenuItem value={11} primaryText="Team10" /> <MenuItem value={12} primaryText="Team11" /> <MenuItem value={13} primaryText="Team12" /> <MenuItem value={14} primaryText="Team13" /> <MenuItem value={15} primaryText="Team14" /> <MenuItem value={16} primaryText="Team15" /> </SelectField> </div> </MuiThemeProvider> ); } } export default Team; 

The textField component

 import React, {Component} from 'react'; import MenuItem from 'material-ui/MenuItem'; import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; import getMuiTheme from 'material-ui/styles/getMuiTheme'; import TextField from 'material-ui/TextField'; import test from '../selectComponent/SelectComponent'; import {disable1} from '../radioButton/RadioBtn'; // let disable1 = false; // disable1 = test; const styles = { errorStyle: { borderColor: 'red', color: 'red', }, underlineStyle: { borderColor: "#000", }, underlineFocusStyle: { borderColor: "#005FA8", }, floatingLabelStyle: { color: '#000', }, floatingLabelFocusStyle: { color: '#000', }, hintStyle: { color: '#000', } }; class Users extends Component { render (){ return ( <MuiThemeProvider> <div> <TextField hintText="Search for a user" underlineFocusStyle={styles.underlineFocusStyle} underlineStyle={styles.underlineStyle} errorStyle={styles.errorStyle} hintStyle={styles.hintStyle} disabled={disable1} /> </div> </MuiThemeProvider> ) }} export default Users; 

I haven't used Material UI yet but I think this can be fixed just with getting the React components talking with each other correctly. I'm making the assumption that your radio buttons group, textField, and selectField are siblings under a single component (I'll go with the name “Main” for example's sake).

It's obviously common in React to have the values in one component affect the rendering of another non-child component. So, we'll have to make the components talk to each other. However, they can't do that directly so everything is going to have to move to the Main component first and then back down the family tree to properly render your pieces. Here is the flow I would do:

Radio Buttons Value Changed -> Send value to Main (via prop) -> When Main updates, conditionally render different components based on new values

So, the first thing we'd need to do is to store whether or not the field should be enabled. In Main we'll start off by initializing a Boolean variable:

constructor(){
    super();
    this.state = {
        textFieldDisabled: false
    };
}

Additionally, we need a method to modify that value, which we'll end up passing as a prop to the radio button component:

setFieldDisabled(val){
    this.setState ({
        textFieldDisabled: val
    });
}

While we're here we'll add the following to the constructor method to ensure that setFieldDisabled() is bound to the Main componenet:

this.setFieldDisabled= this.setFieldDisabled.bind(this);

When you render the radio buttons you'll want to pass setFieldDisabled in as a prop so you'll have access to it and will be able to modify Main's state via its child:

<RadioBtn setFieldDisabled={this.setFieldDisabled} />

Moving on to your RadioBtn component, probably in your change() method you can call the prop it recieved, which target's Main's method. Here you'll write your logic to determine whether or not the text field should be shown, then send that value back to Main using:

this.props.setFieldDisabled(val);

Now we have a variable that all sub-components of Main can easily access. The last thing we'll have to do is pass that value from Main to the textField component:

<textField disabled={this.state.textFieldDisabled} />

And inside that component you'd use {this.props.disabled} for your value of disabled in the TextField. You could do the same for the selectField component as well and modify the values you're passing to Main, though from the sounds of it I think only the textField component is being turned on and off here. I hope that helps!

You can also look in to conditional rendering if you want to render different components altogether.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM