Disabling a Button Within a Stateless Component - React

Disabling a button within a stateless component - react

I'd use a local state just for the value of the input. This would make it a controlled component.

class Childprop extends React.Component {
state = {
newName: ''
}

handleNameChange = (e) => {
e.preventDefault();
props.onNameChange(this.state.newName);
this.setState({ newName: '' });
}

render() {
return (
<div>
The logged in user is: {props.nameProp}
<form onSubmit={handleNameChange}>
<input name="newName" type="text" id="input" onChange={(e) => this.setState(e.target.value)} value={this.state.newName} />
<input type="submit" disabled={this.state.newName.length === 0} />
</form>
</div>
);
}
};

React functional component: enable/disable button based on a state value

Option tag must have "value" property.
Check this: https://www.w3schools.com/tags/att_option_value.asp

Disable submit button in React functional component if all input fields are not completed

Your expression is actually wrong. It should be:

disabled={
user.length < 1 ||
pass.length < 1 ||
email.length < 1 ||
app.length < 1
}

When any one is correct, then it should be disabled. So keep it in || comparison. In simple words, what you're checking is for error is true. Then, you're supposed to see:

  • If user length is less than 1
  • OR pass length is less than 1
  • OR email length is less than 1
  • OR app length is less than 1

If any one of those above conditions are true, then it's wrong. So you have to use || and not &&! Full code below:

import React, { useState } from "react";
import TextField from "@material-ui/core/TextField";
import MenuItem from "@material-ui/core/MenuItem";
import { makeStyles } from "@material-ui/core/styles";
import Button from "@material-ui/core/Button";
import { appList, apisList } from "./appList";

const useStyles = makeStyles(theme => ({
root: {
"& .MuiTextField-root": {
margin: theme.spacing(0.7),
width: "30ch"
}
}
}));

const submitButtonStyle = {
marginLeft: "7px",
marginTop: "15px",
marginBottom: "15px"
};

function FormPage() {
const classes = useStyles();
// const formState = { user: '',pass: '', email: '', app: ''};
// const [login, setLogin] = useState(formState);
// const { user, pass, email, app, } = login;
const [user, setUser] = useState("");
const [pass, setPass] = useState("");
const [email, setEmail] = useState("");
const [app, setApp] = useState("");

const handleUser = e => {
setUser(e.target.value);
console.log(user);
};
const handlePass = e => {
setPass(e.target.value);
};
const handleEmail = e => {
setEmail(e.target.value);
};
const handleApp = e => {
setApp(e.target.value);
};

const handleSubmit = e => {
e.preventDefault();
const login = { user: user, pass: pass, email: email, app: app };

console.log(login);
};

return (
<div>
<form
className={classes.root}
noValidate
autoComplete="off"
onSubmit={handleSubmit}
>
<div>
<TextField
required
name="user"
id="outlined-helperText"
label="Integration Username"
onChange={e => {
handleUser(e);
}}
value={user}
variant="outlined"
/>

<TextField
required
name="pass"
id="outlined-password-input"
label="Integration Password"
type="password"
onChange={e => handlePass(e)}
value={pass}
autoComplete="current-password"
variant="outlined"
/>
<TextField
required
name="email"
id="outlined-helperText"
label="Email"
value={email}
onChange={e => handleEmail(e)}
variant="outlined"
/>

<TextField
required
name="app"
select
label="Select app to redirect"
value={app}
onChange={e => handleApp(e)}
helperText=""
variant="outlined"
>
{appList.map(app => (
<MenuItem key={app.value} value={app.value}>
{app.label}
</MenuItem>
))}
</TextField>
</div>
</form>
<Button
style={submitButtonStyle}
variant="contained"
color="primary"
onClick={handleSubmit}
disabled={
user.length < 1 ||
pass.length < 1 ||
email.length < 1 ||
app.length < 1
}
>
Submit
</Button>
</div>
);
}

export default FormPage;

how to disable a button in React imported into another component?

Your Submit button doesn't allow for setting any other props on the underlying button component. It should proxy though any props you want to be externally configured by what is rendering the Submit button. I also suggest explicitly declaring the button type to be "submit", or also exposing that prop out in the component API.

Your proxying of the onClick handler also drops the click event, that should be passed through in case any consuming component care about it.

class Submit extends Component {
render() {
const { disabled, onClick, type = "submit" } = this.props;
return (
<button
className="button"
disabled={disabled}
onClick={onClick}
type={type}
>
SUBMIT
</button>
);
}
}

For such a simple component with no internal logic IMO a functional component is a better option, and I would name it more clearly.

const SubmitButton = ({ disabled, onClick, type = "submit" }) => (
<button
className="button"
disabled={disabled}
onClick={onClick}
type={type}
>
SUBMIT
</button>
);

Now when you are using the submit button from a parent component you can pass in a disabled prop based on any condition you need/require.

  render() {
const { submitDisabled } = this.state;
return (
<div className="table">
<div className="table-actions">
{this.renderRefresh()}
<SubmitButton
disabled={submitDisabled} // <-- pass disabled value
onClick={this.submitForm} // <-- attach click handler
type="button" // <-- so we don't accidentally take default form action
/>
</div>
</div>
);
}
}

How you compute/set this.state.submitDisabled is up to you. Maybe it is disabled when the form is being submitted, for example.

submitForm = () => {
this.setState({ submitDisabled: true });
...
};

Disabled button if status disabled

There are multiple ways of doing this. This would be the most straightforward (but keep reading):

const MainComponent = ({component}) => {
const [disabled, setDisabled] = useState(false);

return (<div>
<Button
onClick={() => {createItem(); setDisabled(true);}}
disabled={disabled}
>
Button
<Button/>
</div>);
};

However, since createItem doesn't appear in your code, I assume that it is a function in the parent scope of your component. If that is the case, then the status should be tracked there and you should get rid of the useState in this component. You'd then just use the (reactive) prop to set the button state:

const MainComponent = ({component, createItem}) => {
return (<div>
<Button
onClick={createItem}
disabled={component.status === 'disabled'}
>
Button
<Button/>
</div>);
};


Related Topics



Leave a reply



Submit