I have some radio buttons which are setting the rate type that I use with clients. This works as far as choosing one, and it sets that value. However, the next time I load this data, it does not render the button that was previously chosen as selected. It looks to me like I have it setup exactly the same way as I have it working in other code. So I'm sure it's something simple, but I can't seem to find it.
Once I click the buttons, they do render the correct one as selected and change the value in the database as expected. But as I said, when I load this again, it does bring in the data and set the state with the correct value through the function getRateType().
It just doesn't show which button is selected. My assumption is it's something to do with that I set the state initially to "", but why doesn't it update when I change the state to the correct value?
import React, { Component } from 'react';
import { Row, Col, Form, Modal, Button, Jumbotron, Table} from 'react-bootstrap';
import { config } from '../../Config/Constants';
import debounce from 'lodash.debounce';
const API_URL = config.url.API_URL;
class Project extends Component {
constructor(props) {
super(props);
this.state = {
rateType: ""
}
}
componentDidMount() {
this.getRateType(this.props.billProjId);
}
getRateType = (projId) => {
fetch(API_URL `/billingcalculator/projects/${projId}`)
.then((res) => {
if (!res.ok) {
throw new Error()
}
return res.json()
})
.then((result) => {
this.setState({ rateType: result[0].project_type });
console.log(this.state.rateType); <-- this shows the correct value
})
.catch((error) => {
console.log(error);
})
}
handleCheck = (e) => {
this.setState({ [e.target.name]: e.target.value },
() => this.updateDB())
}
updateDB = debounce(() => {
let data = {
rateType: this.state.rateType
};
this.updateRateType(data);
}, 1500);
updateRateType(data) {
fetch(API_URL `/billingcalculator/project/update`, {
method: "PUT",
body: JSON.stringify({
projectId: this.props.billProjId,
data: data,
}),
headers: { "Content-Type": "application/json" },
})
.then((res) => {
if (!res.ok) {
throw new Error();
}
return res.json();
})
.catch((err) => console.log(err))
.then(this.renderAgain());
}
render() {
return (
<div>
<Jumbotron className="mt-3">
<h1 className='display-4'>Project: {this.props.projectName}</h1>
<p>Project ID:{this.props.billProjId}</p>
<Form>
<Form.Group
as={Row}
name="rateType"
controlId="rateType"
onChange={this.handleCheck}
>
<Form.Check
inline
label="profit"
name="rateType"
type="radio"
id="rateType-profit"
value="profit"
defaultChecked={this.state.rateType === "profit"}
/>
<Form.Check
inline
label="non-profit"
name="rateType"
type="radio"
id="rateType-non-profit"
value="non-profit"
defaultChecked={this.state.rateType === "non-profit"}
/>
<Form.Check
inline
label="existing-client"
name="rateType"
type="radio"
id="rateType-existing"
value="existing"
defaultChecked={this.state.rateType === "existing"}
/>
</Form.Group>
</Form>
</Jumbotron>
</div>
)
}
}
export default Project;
CodePudding user response:
Use checked instead of defaultChecked if your checkbox is going to be updated after a component re-render
render() {
return (
<div>
<Jumbotron className="mt-3">
<h1 className='display-4'>Project: {this.props.projectName}</h1>
<p>Project ID:{this.props.billProjId}</p>
<Form>
<Form.Group
as={Row}
name="rateType"
controlId="rateType"
onChange={this.handleCheck}
>
<Form.Check
inline
label="profit"
name="rateType"
type="radio"
id="rateType-profit"
value="profit"
checked={this.state.rateType === "profit"}
/>
<Form.Check
inline
label="non-profit"
name="rateType"
type="radio"
id="rateType-non-profit"
value="non-profit"
checked={this.state.rateType === "non-profit"}
/>
<Form.Check
inline
label="existing-client"
name="rateType"
type="radio"
id="rateType-existing"
value="existing"
checked={this.state.rateType === "existing"}
/>
</Form.Group>
</Form>
</Jumbotron>
</div>
)
}
