I am trying to set the state of my brandSelect prop in ReactJS using React Select however I am confused to how this can be done?
Here is my current code:
class VehicleSelect extends React.Component {
constructor(props) {
super(props);
this.state = { brandSelect: ""};
}
render() {
var options = [
{ value: 'Volkswagen', label: 'Volkswagen' },
{ value: 'Seat', label: 'Seat' }
];
return (
<Select
name="form-field-name"
value={this.state.brandSelect}
options={options}
placeholder="Select a brand"
searchable={false}
onChange={}
/>
)
}
};
When the option is selected I want the state to be set as the option chosen.
Does anybody know how this is done with React Select as the documentation doesn't really cover this? So far I have tried making a function with a set state attached to the onChange prop however this didn't work.
In react 16.8+ the implementation should look like this using React hooks:
Hooks are a new addition in React 16.8
function VehicleSelect() {
const options = [
{ value: 'volkswagen', label: 'Volkswagen' },
{ value: 'seat', label: 'Seat' }
];
const [selectedOption, setSelectedOption] = useState({ value: 'volkswagen', label: 'Volkswagen' });
const [handleChange] = useState(() => {
return () => {
setSelectedOption(selectedOption);
};
});
return (
<div className="App">
<Select
name="form-field-name"
placeholder="Select a brand"
searchable={false}
value={selectedOption}
onChange={handleChange}
options={options}
/>
</div>
);
}
You can try do add _onChange handler to your component, that will handle changes form <Select /> component.
class VehicleSelect extends React.Component {
constructor(props) {
super(props);
this.state = { brandSelect: ""};
}
_onChange(value) {
//console.log(value) - just to see what we recive from <Select />
this.setState({brandSelect: value});
}
render() {
var options = [
{ value: 'Volkswagen', label: 'Volkswagen' },
{ value: 'Seat', label: 'Seat' }
];
return (
<Select
name="form-field-name"
value={this.state.brandSelect}
options={options}
placeholder="Select a brand"
searchable={false}
onChange={this._onChange.bind(this)}
/>
)
}
};
Try this:
class VehicleSelect extends React.Component {
constructor(props) {
super(props);
this.state = {
brandSelect: ""
};
}
onSelectChanged(value) {
this.setState({
brandSelect: value
});
}
render() {
var options = [{
value: 'Volkswagen',
label: 'Volkswagen'
}, {
value: 'Seat',
label: 'Seat'
}];
<Select
name="form-field-name"
value={this.state.brandSelect}
options={options}
placeholder="Select a brand"
searchable={false}
onChange={this.onSelectChanged.bind(this)}
/>
You need an onChange event handler. Pass in an argument to the event handler function which in this case will be the selected value of the Select input and then Set the State of the brandSelect with the selected value.
I used this in my code to work with Selector:
class VehicleSelect extends React.Component {
constructor(props) {
super(props);
this.state = { brandSelect: ""};
}
onChange(event) {
this.setState({brandSelect: event.target.value}); // important
}
render() {
var options = [
{ value: 'Volkswagen', label: 'Volkswagen' },
{ value: 'Seat', label: 'Seat' }
];
return (
<Select
name="form-field-name"
value={this.state.brandSelect}
options={options}
placeholder="Select a brand"
searchable={false}
onChange={this.onChange.bind(this)}
/>
)
}
};
const Layout = (props: any) => {
//Row First
const [rows, setRow] = useState({
rowFirst: "",
columnFirst: "",
columnSecond: 0
});
const handleChangeRowFirst = (e: { target: { name: any; value: any; }; }) => {
setRow({ ...rows, [e.target.name]: e.target.value });
console.log("row", rows);
props.dispatch({
type: "setRow",
payload: rows
});
};
const onSubmitForm = (e: any) => {
e.preventDefault();
if (!rows.rowFirst) {
alert("rowFirst is empty.")
}
else if (!rows.columnFirst) {
alert("columnFirst or rowFirst is empty.")
}
else if (!rows.columnSecond) {
alert("columnSecond is empty.")
}
}
return (
<>
<Grid container className="containerMatrix">
<form onSubmit={onSubmitForm} className="formMatrix">
<Grid item xs={6} md={5}>
<Box id="test" className="martixNum">
<Typography variant="h5" gutterBottom className="nameColMatrix">
Enter Numbers First Matrix
</Typography>
<Box className="martixFirst">
<TextField
type="number"
InputProps={{
inputProps: {
max: 99, min: 0
}
}}
label="Row" onChange={handleChangeRowFirst} name="rowFirst" id="num1" value={rows.rowFirst}
/>
<TextField
type="number"
InputProps={{
inputProps: {
max: 99, min: 0
}
}}
label="Column" onChange={handleChangeRowFirst} name="columnFirst" id="num2" value={rows.columnFirst}
/>
</Box>
</Box>
</Grid>
<Grid item xs={6} md={5}>
<Box id="test" className="martixNum">
<Typography variant="h5" gutterBottom className="nameColMatrix">
Enter Numbers Second Matrix
</Typography>
<Box className="martixFirst">
<TextField
type="number"
InputProps={{
inputProps: {
max: 99, min: 0
}
}}
label="Row" onChange={handleChangeRowFirst} name="columnFirst" id="num3" value={rows.columnFirst}
/>
<TextField
type="number"
InputProps={{
inputProps: {
max: 99, min: 0
}
}}
label="Column" onChange={handleChangeRowFirst} name="columnSecond" id="num4"
/>
</Box>
</Box>
</Grid>
<Grid item xs={6} md={5}>
<Box>
<Button variant="contained" color="primary" type="submit">
Primary
</Button>
</Box>
</Grid>
</form>
</Grid>
</>
)
}
Related
I formerly have a checkbox like this
renderCategoriesMD() {
const { classes, categoriesArray } = this.props;
const { checkedCategories, reset } = this.state;
if (categoriesArray && categoriesArray.length > 0) {
return categoriesArray.map((cat, index) => {
return (
<div>
<FormControlLabel
key={index}
control={
<Checkbox
tabIndex={-1}
onClick={() => this.handleToggleCats(index)}
checked={checkedCategories.indexOf(index) !== -1}
checkedIcon={<Check className={classes.checkedIcon} />}
icon={<Check className={classes.uncheckedIcon} />}
classes={{
checked: classes.checked,
root: classes.checkRoot,
}}
/>
}
classes={{ label: classes.label }}
label={
<Typography style={{ fontSize: 13 }}>
{cat.name || ""}
</Typography>
}
/>
{!reset && (
<div style={{ marginLeft: 10 }}>
{this.renderUnderSubCategoriesMD(cat)}
</div>
)}
</div>
);
});
}
return null;
}
What this does is populate options of checkboxes like the image below.
what i want to achieve now is to have react-select of multiple options so instead of checkboxes i can select the options from react select.
<Select
value={this.state.value}
name="filter__statistics"
options={options}
onChange={this.handleChange}
multi={true}
/>
I recommend you to use the npm packages, it is very easy to use and implement. npm react-select
There is an example
import React from 'react';
import Select from 'react-select';
const options = [
{ value: 'chocolate', label: 'Chocolate' },
{ value: 'strawberry', label: 'Strawberry' },
{ value: 'vanilla', label: 'Vanilla' },
];
class App extends React.Component {
state = {
selectedOption: null,
};
handleChange = selectedOption => {
this.setState({ selectedOption });
console.log(`Option selected:`, selectedOption);
};
render() {
const { selectedOption } = this.state;
return (
<Select
value={selectedOption}
onChange={this.handleChange}
options={options}
/>
);
}
}
I am new to react so I might be missing something
I am using react-select to store multiple elements and am using the map function to display elements which is working fine. But when I am using the same element in another class to display in a list element it shows a blank.
Here is the code where I am displaying the multiple options.
const Departments = [
{ label: "OneIT", value: "OneIT" },
{ label: "HR", value: "HR" },
{ label: "Vigilance", value: "Vigilance" },
{ label: "Ethics", value: "Ethics" },
{ label: "Corporate Services", value: "Corporate Services" },
{ label: "Legal", value: "Legal" },
{ label: "Sports", value: "Sports" },
{ label: "TQM", value: "TQM" },
{ label: "Iron Making", value: "Iron Making" },
{ label: "TMH", value: "TMH" },
];
class MultiSelect2 extends Component {
state = {
selectedOptions: [],
};
handleChangeField = (selectedOptions) => {
this.setState({ selectedOptions });
};
render() {
const { selectedOption } = this.state;
return (
<div className="container">
<div className="row">
<div className="col-md-2"></div>
<div className="col-md-8">
<span>Select Department</span>
<Select
value={selectedOption}
options={Departments}
onChange={this.handleChangeField}
isMulti
/>
{this.state.selectedOptions.map((o) => (
<p>{o.value}</p>
))}
</div>
<div className="col-md-4"></div>
</div>
</div>
);
}
}
I am trying to display this in another class in the list item but it is not showing.
export class Confirm extends Component {
state = {
selectedOptions: [],
};
render() {
const {
values: { selectedOptions },
} = this.props;
return (
<List>
<ListItemText primary="Departments" secondary={selectedOptions} />
</List>
);
}
}
I know I might be missing something very basic but please help
#Kubwimana Adrien
Here is the rest of the code:
export class Confirm extends Component {
state = {
rows: [],
idx: [],
selectedOptions: []
};
continue = e => {
e.preventDefault();
//Process Form//
this.props.nextStep();
};
back = e => {
e.preventDefault();
this.props.prevStep();
};
render() {
const {
values: {
Title,
Details,
What,
Why,
How,
Status,
Cost,
Benefits,
Kpi_Before,
Kpi_After,
Time,
dateTime,
Base_Before,
Target_Before,
UOM_Before,
idx,
selectedOptions
}
} = this.props;
return (
<MuiThemeProvider theme={theme}>
<React.Fragment>
<div className={useStyles.root}>
<AppBar position="static">
<Toolbar>
<Typography
gutterBottom
align="center"
style={{ width: "100%", alignItems: "center" }}
>
Confirm Information
</Typography>
</Toolbar>
</AppBar>
</div>
<br />
<h3>Are you sure to continue and confirm your information?</h3>
<List>
<ListItemText primary="Departments" secondary={selectedOptions} />
<ListItemText primary="Title" secondary={Title} />
<ListItemText primary="Kpi_Before" secondary={Kpi_Before} />
</List>
<p> {this.state.selectedOptions.map(o => (
<p>{o.value}</p>
))}</p>
<br />
<Button
variant="contained"
color="primary"
style={styles.button}
onClick={this.continue}
>
Confirm & Continue
</Button>
<Button
variant="contained"
color="default"
style={styles.button}
onClick={this.back}
>
Back
</Button>
</React.Fragment>
</MuiThemeProvider>
);
}
}
const theme = createMuiTheme({
palette: {
primary: blue,
secondary: purple
},
status: {
danger: "orange"
}
});
const styles = {
button: {
margin: 15
}
};
export default Confirm;
I have used redux-form for the form. I have developed a wizard considering an example from the documentation. The wizard is working but when i go to step 2 i.e SyncAccount component which has the form and fill that form and hit the next button to go to another step and hit the back button to go back to the SyncAccount component then the form is cleared. I have used destroyOnUnmount but it is not solving my issue either. What have i missed?
only second page i.e SyncAccount has only form. First and third do not have.
here is the code
AccountSteps.js
const mapDispatchToProps = dispatch => ({
getUser: () => dispatch(getCurrentUser()),
postWizard: (userObj, wizardType) =>
dispatch(postWizardData(userObj, wizardType)),
updateWizard: (userObj, wizardType) =>
dispatch(updateWizardData(userObj, wizardType)),
});
const mapStateToProps = state => ({
userData: state.userReducer,
wizard: state.wizardReducer,
});
class AccountSteps extends React.Component<{
user: Object,
wizard: Object,
postWizard: Function,
updateWizard: Function,
getUser: Function
}> {
constructor(props) {
super(props);
this.state = {
page: 0,
steps: [
{ steps: 0, label: 'Privacy' },
{ steps: 1, label: 'Sync Your Account' },
{ steps: 2, label: 'Install Extension' },
],
};
}
componentDidMount() {
this.props.getUser();
}
static getDerivedStateFromProps(nextProps, prevState) {
const { wizard } = nextProps;
if (!isEmpty(wizard) && wizard.page !== prevState.page) {
return {
page: wizard.page,
};
}
return null;
}
nextPage = (userObj, type) => {
this.props.postWizard(userObj, type);
};
previousPage = (wizardData) => {
console.log('wizardData', wizardData);
this.props.updateWizard(wizardData);
};
render() {
const { page, steps } = this.state;
return (
<Wrapper>
<CardWrapper>
<Stepper activeStep={page} alternativeLabel>
{steps.map(step => (
<Step key={step.steps}>
<StepLabel>{step.label}</StepLabel>
</Step>
))}
</Stepper>
{page === 0 && (
<Privacy
{...this.props}
activeStep={page}
back={this.previousPage}
next={this.nextPage}
/>
)}
{page === 1 && (
<SyncAccount
{...this.props}
activeStep={page}
back={this.previousPage}
next={this.nextPage}
/>
)}
{page === 2 && (
<Extension
{...this.props}
activeStep={page}
back={this.previousPage}
next={this.nextPage}
/>
)}
</CardWrapper>
</Wrapper>
);
}
}
export default connect(
mapStateToProps,
mapDispatchToProps,
)(AccountSteps);
SyncAccount.js
const SyncAccount = ({
user,
emailProvider,
handleProviderChange,
handleChange,
...props
}: {
user: Object,
emailProvider: string,
handleProviderChange: Function,
handleChange: Function
}) => {
console.log('props in Sync', user.email);
return (
<SyncWrapper>
<IconsWrapper>
<CustomSync style={{ fontSize: 30 }} color="action" />
<Mail style={{ fontSize: 50 }} color="secondary" />
</IconsWrapper>
<p>Please enter your email address which you want to sync with us.</p>
<FormWrapper>
<span>Email Provider: </span>
<RadioGroup
aria-label="emailProvider"
name="provider"
style={{ display: 'flex', flexDirection: 'row' }}
value={user.provider}
onChange={handleChange}
>
<FormControlLabel
value="google"
control={<Radio color="primary" />}
label="Google"
/>
<FormControlLabel
value="imap"
control={<Radio color="primary" />}
label="IMAP"
/>
</RadioGroup>
<StyledField
label="Email"
id="email"
name="email"
type="email"
value={user.email}
onChange={handleChange}
placeholder="Email"
component={GTextField}
required
/>
<StyledField
label="Password"
id="password"
name="password"
type="password"
value={user.password}
onChange={handleChange}
placeholder="Password"
component={GPasswordField}
required
/>
<StyledField
label="Job title"
id="jobTitle"
name="job_title"
value={user.job_title}
onChange={handleChange}
placeholder="Job Title"
component={GAutoCompleteField}
required
/>
<Footer
{...props}
userObj={user}
type="sync"
wizardData={{ step_index: 0, wizard_name: 'privacy' }}
disabled={user && (!user.email || !user.password || !user.job_title)}
/>
</FormWrapper>
</SyncWrapper>
);
};
export default enhance(SyncAccount);
enhance.js
const requiredFields = {
email: 'Email',
password: 'Password',
job_title: 'Job Title',
};
const withReduxForm = reduxForm({
form: 'syncAccount',
fields: requiredFields,
destroyOnUnmount: false,
forceUnregisterOnUnmount: true,
validate,
});
const mapStateToProps = state => ({
wizard: state.wizardReducer,
});
const enhance = compose(
connect(
mapStateToProps,
null,
),
withReduxForm,
withState('user', 'updateUser', {
email: '',
password: '',
job_title: '',
provider: 'google',
wizard_name: 'extension',
step_index: 2,
}),
withHandlers({
handleChange: props => (ev) => {
if (ev.target) {
return props.updateUser({
...props.user,
[ev.target.name]: ev.target.value,
});
}
return props.updateUser({
...props.user,
job_title: ev.name,
});
},
}),
);
export default enhance;
I'm using material-ui and react-charts-js to build a page that fetches from backend and displays data.
I'm having some trouble in understanding how to correctly display MyGraph.
The page contains two Date Picker, a Toggle and a Raised Button.
I'd like to display in the second Tab the graph after the data is chosen and user's click on the button, then reset the data and repeat again.
These are some attemps but with this strategy, the MyGraph is correctly displayed but when it calls this.props.onCreated(), this.state.buttonClicked is false and the graph is hidden.
MyCard.js
import React from 'react';
import {Card, Tabs, Tab, FontIcon, DatePicker, Toggle, GridList, GridTile, SelectField, MenuItem, RaisedButton} from 'material-ui/';
import MyGraph from './MyGraph';
const styles = {
root: {
display: 'flex',
flexWrap: 'wrap',
justifyContent: 'space-around',
margin: '0 auto'
},
gridList: {
width: 200,
height: 500,
overflowY: 'auto',
},
};
export default class MyCard extends React.Component {
constructor(props){
super(props)
this.state = {
queryNumber: 1,
startDate: null,
endDate: null,
sameRegion: true,
buttonDisabled: true,
buttonClicked: false
}
}
handleQueryNumberChange = (event, index, value) => {
this.setState({queryNumber: value});
}
check(){
if (this.state.startDate && this.state.endDate) {
this.setState({buttonDisabled: false})
}
}
handleStartDateChange = (event, date) => {
this.setState({
startDate: date,
}, this.check);
};
handleEndDateChange = (event, date) => {
this.setState({
endDate: date,
}, this.check);
};
handleSameRegionChange = (event, isInputChecked) =>{
this.setState({sameRegion: isInputChecked});
}
handleClick = (event) =>{
this.setState({buttonClicked: true})
}
resetForm = () =>{
this.setState({buttonClicked: false, startDate: null, endDate: null, buttonDisabled: true})
}
render() {
return (
<Card>
<Tabs>
<Tab icon={<FontIcon className="material-icons" >date_range</FontIcon>} label="Pick">
<div style={styles.root}>
<GridList
cols={1}
cellHeight={100}
padding={1}
style={styles.gridList}
>
<GridTile>
<SelectField
floatingLabelText="Query"
value={this.state.queryNumber}
onChange={this.handleQueryNumberChange}
>
<MenuItem value={1} primaryText="Date" />
<MenuItem value={2} primaryText="Query2" />
<MenuItem value={3} primaryText="Query3" />
<MenuItem value={4} primaryText="Query4" />
<MenuItem value={5} primaryText="Query5" />
</SelectField>
</GridTile>
<GridTile>
<DatePicker hintText="Select start date" value={this.state.startDate} onChange={this.handleStartDateChange}/>
</GridTile>
<GridTile>
<DatePicker hintText="Select end date" value={this.state.endDate} onChange={this.handleEndDateChange}/>
</GridTile>
<GridTile>
<Toggle label="Same Region" defaultToggled={true} onToggle={this.handleSameRegionChange}/>
</GridTile>
<GridTile>
<RaisedButton label="Send" secondary={true} disabled={this.state.buttonDisabled} onClick={this.handleClick}/>
</GridTile>
</GridList>
</div>
</Tab>
<Tab icon={<FontIcon className="material-icons" >pie_chart</FontIcon>} label="Graph">
<div>
{this.state.buttonClicked && <MyGraph values={this.state} onCreated={this.resetForm}/>}
</div>
</Tab>
</Tabs>
</Card>
);
}
}
MyGraph.js
import React from 'react';
import {Pie} from 'react-chartjs-2';
import moment from 'moment'
export default class MyGraph extends React.Component {
constructor(props) {
super(props);
this.state = {
data: props,
labels: [],
datasets: [{
data: [],
backgroundColor: [
'#d50000',
'#2962ff',
'#00c853',
'#ffab00'
],
hoverBackgroundColor: [
'#ff5252',
'#448aff',
'#69f0ae',
'#ffd740'
]
}]
}
}
call(){
this.callApi()
.then(res => {
console.log(res)
let datasetsModified = this.state.datasets;
let labelsModified = this.state.labels;
datasetsModified[0].data.length = 0;
labelsModified.length = 0;
for(let resource of res){
datasetsModified[0].data.push(resource.avg)
labelsModified.push(resource._id)
}
this.setState({
labels: labelsModified,
datasets: datasetsModified,
})
})
.then(() =>{
this.props.onCreated()
})
.catch(err => console.log(err))
}
async callApi(){
var query = 'http://localhost:3100/api/pings/query/avgInDay?start='+moment(this.state.data.values.startDate).format('YYYY-MM-DD')+'&end='+moment(this.state.data.values.endDate).format('YYYY-MM-DD')+'&sameRegion='+((this.state.data.values.sameRegion === true) ? 0 : 1)
const response = await fetch(query);
const body = await response.json();
return body;
}
componentDidMount(){
this.call()
}
componentWillReceiveProps(nextProps) { // Successives rendering
console.log('will')
this.setState({data: nextProps}, this.call())
}
render() {
return (
<Pie data={this.state} width={500} height={500} options={{maintainAspectRatio: false}}/>
);
}
}
Can anyone illustrate the correct way to do this?
Thanks in advance :)
EDIT 1: I've tried to lift the state up, it's doing what I want but MyGraph is called every single modify before the click; is this ok?
And finally, my labels and data are updated, but not the slices
MyCard.js
import React from 'react';
import {Card, Tabs, Tab, FontIcon, DatePicker, Toggle, GridList, GridTile, SelectField, MenuItem, RaisedButton} from 'material-ui/';
import MyGraph from './MyGraph';
import moment from "moment/moment";
const styles = {
root: {
display: 'flex',
flexWrap: 'wrap',
justifyContent: 'space-around',
margin: '0 auto'
},
gridList: {
width: 200,
height: 500,
overflowY: 'auto',
},
};
export default class MyCard extends React.Component {
constructor(props){
super(props)
this.state = {
queryNumber: 1,
startDate: null,
endDate: null,
sameRegion: true,
buttonDisabled: true,
buttonClicked: false,
graphData: {
data: props,
labels: [],
datasets: [{
data: [],
backgroundColor: [
'#d50000',
'#2962ff',
'#00c853',
'#ffab00'
],
hoverBackgroundColor: [
'#ff5252',
'#448aff',
'#69f0ae',
'#ffd740'
]
}]
}
}
}
handleQueryNumberChange = (event, index, value) => {
this.setState({queryNumber: value});
}
check(){
if (this.state.startDate && this.state.endDate) {
this.setState({buttonDisabled: false})
}
}
handleStartDateChange = (event, date) => {
this.setState({
startDate: date,
}, this.check);
};
handleEndDateChange = (event, date) => {
this.setState({
endDate: date,
}, this.check);
};
handleSameRegionChange = (event, isInputChecked) =>{
this.setState({sameRegion: isInputChecked});
}
handleClick = (event) =>{
this.callApi()
.then(res => {
console.log(res)
let graphDataModified = this.state.graphData;
let datasetsModified = graphDataModified.datasets;
let labelsModified = graphDataModified.labels;
datasetsModified[0].data.length = 0;
labelsModified.length = 0;
for(let resource of res){
datasetsModified[0].data.push(resource.avg)
labelsModified.push(resource._id)
}
this.setState({graphData: graphDataModified, buttonClicked: true})
})
.then(() =>{
this.resetForm()
})
.catch(err => console.log(err))
}
async callApi(){
var query = 'http://localhost:3100/api/pings/query/avgInDay?start='+moment(this.state.startDate).format('YYYY-MM-DD')+'&end='+moment(this.state.endDate).format('YYYY-MM-DD')+'&sameRegion='+((this.state.sameRegion === true) ? 0 : 1)
const response = await fetch(query);
const body = await response.json();
return body;
}
resetForm = () =>{
this.setState({startDate: null, endDate: null, buttonDisabled: true})
}
render() {
return (
<Card>
<Tabs>
<Tab icon={<FontIcon className="material-icons" >date_range</FontIcon>} label="Pick">
<div style={styles.root}>
<GridList
cols={1}
cellHeight={100}
padding={1}
style={styles.gridList}
>
<GridTile>
<SelectField
floatingLabelText="Query"
value={this.state.queryNumber}
onChange={this.handleQueryNumberChange}
>
<MenuItem value={1} primaryText="Date" />
<MenuItem value={2} primaryText="Query2" />
<MenuItem value={3} primaryText="Query3" />
<MenuItem value={4} primaryText="Query4" />
<MenuItem value={5} primaryText="Query5" />
</SelectField>
</GridTile>
<GridTile>
<DatePicker hintText="Select start date" value={this.state.startDate} onChange={this.handleStartDateChange}/>
</GridTile>
<GridTile>
<DatePicker hintText="Select end date" value={this.state.endDate} onChange={this.handleEndDateChange}/>
</GridTile>
<GridTile>
<Toggle label="Same Region" defaultToggled={true} onToggle={this.handleSameRegionChange}/>
</GridTile>
<GridTile>
<RaisedButton label="Send" secondary={true} disabled={this.state.buttonDisabled} onClick={this.handleClick}/>
</GridTile>
</GridList>
</div>
</Tab>
<Tab icon={<FontIcon className="material-icons" >pie_chart</FontIcon>} label="Graph">
<div>
{ this.state.buttonClicked ? <MyGraph data={this.state.graphData}/> : null }
</div>
</Tab>
</Tabs>
</Card>
);
}
}
MyGraph.js
import React from 'react';
import {Pie} from 'react-chartjs-2';
export default class MyGraph extends React.Component {
render() {
console.log(this.props.data)
return (
<Pie data={this.props.data} width={500} height={500} options={{maintainAspectRatio: false}}/>
);
}
}
I am using antd to create a form and use a fieldDecorator to decorate the various form elements which gives me some extra functionality later.
Everything works fine but I want to create the FormItems in separate files/components and have no idea how to parse this to a new component class.
Here is my code so far which works, but how would I extract and use the existing fieldDecorator in a separate component such as the ProcessSelect component for example.
class ZalosForm extends React.Component {
constructor(...args) {
super(...args);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(e) {
e.preventDefault();
this.props.form.validateFields((err, values) => {
if (!err) {
console.log('Received values of form: ', values);
}
})
}
render() {
const { getFieldDecorator } = this.props.form;
const formItemLayout = {
labelCol: { span: 6 },
wrapperCol: { span: 14 }
};
return (
<div>
<Form inline style={{ marginTop: 10, marginBottom: 10 }} onSubmit={this.handleSubmit}>
<FormItem
{...formItemLayout}
hasFeedback
>
{getFieldDecorator('qualityLabel', {
rules: [{
min: 11, max: 11, message: 'Invalid QL'
}]
})(
<Input style={{ width: '200px' }} size="default" placeholder="QL" />
)}
<FormItem>
<ProcessSelect />
</FormItem>
<FormItem>
<ButtonGroup size="default">
<Button htmlType="submit" size="default" icon="search" onSubmit={this.handleSubmit} />
<Button size="default" icon="close" />
</ButtonGroup>
</FormItem>
</Form>
</div>
)
}
}