React antd steps re-render child component to parent state change - reactjs

I have long registration form which I have divided into parts using steps component of AntD.
// Defined Child Form Components
steps = {
basicInfo: {
title: 'Basic Info',
content: (
<BasicInfoForm
form={this.props.form}
user={this.user}
/>
),
},
addresses: {
title: 'Addresses',
content: (
<Address
form={this.props.form}
addresses={this.user.addresses}
/>
),
},
contactInfo: {
title: 'Contact Info',
content: (
<PhoneForm
form={this.props.form}
contactInfo={this.user.contactInfo}
/>
),
},
}
// Form configuring these child form components
<Form onSubmit={handleSubmit} className="add-edit-user-form">
<Fragment>
<Steps progressDot current={this.state.currentStep}>
{Object.keys(steps).map((key, index) => {
return <Step title={steps && steps[index] ? steps[index].title : null} key={index} />;
})}
</Steps>
<div className={styles['steps-content']}>{steps && steps[currentStep] ? steps[currentStep].content : null}</div>
<div className="steps-action">
{currentStep > 0 && (
<Button style={{ marginLeft: 8 }} onClick={() => this.prev()}>Previous</Button>
)}
{currentStep < steps.length - 1 && (
<Button type="primary" htmlType="submit">Next</Button>
)}
{currentStep === steps.length - 1 && (
<Button type="primary" htmlType="submit">Done</Button>
)}
</div>
</Fragment>
</Form>
// class variable to user object coming from parent.
user = this.props.user ? this.props.user : undefined;
// Child component
interface IAddressFormProps {
form: WrappedFormUtils;
addresses: IAddress[];
fieldName: string;
}
class Address extends Component<IAddressFormProps> {
totalAddresses: any = this.props.addresses && this.props.addresses ?
this.props.addresses : ([{}] as IAddress[]);
state = {
totalAddresses: this.totalAddresses ? this.totalAddresses : ([] as IAddress[]),
};
addAddress = () => {
this.setState((prevState: any) => ({
totalAddresses: [...prevState.totalAddresses, { lineOne: '', lineTwo: '', lineThree: '', city: '', state: '', zip: '', type: '' }],
}));
};
removeAddress = (index: number) => {
this.setState({
totalAddresses: this.state.totalAddresses.filter((item: IAddress, addressIndex: number) => index !== addressIndex),
});
};
render() {
const { getFieldDecorator } = this.props.form;
const fieldName = this.props.fieldName;
return (
<Fragment>
{this.state.totalAddresses.map((item: IAddress, index: number) => {
return (
<Row key={'container-' + index} type="flex" justify="start" gutter={16}>
<Col span={6}>
<Form.Item label="Type" key={'type-' + index}>
{getFieldDecorator(`${fieldName}[${index}].type`, {
initialValue: item.type,
rules: [{ required: true, message: 'Please input address type!' }],
})(
<Select placeholder="Type">
<Option value="Mailing">Mailing</Option>
<Option value="Business">Business</Option>
<Option value="Home">Home</Option>
<Option value="Other">Other</Option>
</Select>
)}
</Form.Item>
<Form.Item label="Line One" key={'lineOne-' + index}>
{getFieldDecorator(`${fieldName}[${index}].lineOne`, {
initialValue: item.lineOne,
rules: [{ required: true, message: 'Please input line one!' }],
})(<Input placeholder="Line One" />)}
</Form.Item>
<Form.Item label="Line Two" key={'lineTwo-' + index}>
{getFieldDecorator(`${fieldName}[${index}].lineTwo`, {
initialValue: item.lineTwo,
rules: [{ required: false, message: 'Please input line two!' }],
})(<Input placeholder="Line Two" />)}
</Form.Item>
<Form.Item label="Line Three" key={'lineThree-' + index}>
{getFieldDecorator(`${fieldName}[${index}].lineThree`, {
initialValue: item.lineThree,
rules: [{ required: false, message: 'Please input line three!' }],
})(<Input placeholder="Line Three" />)}
</Form.Item>
</Col>
<Col span={9}>
<Form.Item label="City" key={'city-' + index}>
{getFieldDecorator(`${fieldName}[${index}].city`, {
initialValue: item.city,
rules: [{ required: true, message: 'Please input city!' }],
})(<Input placeholder="City" />)}
</Form.Item>
<Form.Item label="State" key={'state-' + index}>
{getFieldDecorator(`${fieldName}[${index}].state`, {
initialValue: item.state,
rules: [{ required: true, message: 'Please input state!' }],
})(<Input placeholder="State" />)}
</Form.Item>
<Form.Item label="Zip" key={'zip-' + index}>
{getFieldDecorator(`${fieldName}[${index}].zip`, {
initialValue: item.zip,
rules: [{ required: true, message: 'Please input zip!' }],
})(<Input placeholder="Zip" />)}
</Form.Item>
</Col>
<Col span={4}>
<Button onClick={() => this.removeAddress(index)}>Remove</Button>
</Col>
</Row>
);
})}
<Button onClick={() => this.addAddress()}>Add address</Button>
</Fragment>
);
}
}
I want to maintain the state of user object throughout the steps means going back and forth.
On form submit, updating the user object.
next = (addEditUser: MutationFn<any, any>) => {
const form = this.props.form;
form.validateFields(async (err: any, values: any) => {
if (err) {
return false;
}
values.id = this.userId;
let variables = this.parentId ? { user: values, parentId: this.parentId } : { user: values };
const result = await addEditUser({ variables: variables });
if (result && result.data) {
if (this.state.currentStep === this.state.steps.length - 1) {
this.props.history.push('/user');
} else {
this.user = Object.assign(this.user, values);
const currentStep = this.state.currentStep + 1;
this.setState({ currentStep });
}
}
});
};
The user object is correctly updated but the child components are not. Why?
Thanks in advance.

In order to pass props to the state you have to use the getDerivedStateFromProps method.
In your child class you can add the following - This is an example for your Address Component where you receive the address from the parent Component via props
static getDerivedStateFromProps(props, state) {
const { address } = props;
if(address !== state.address) return { address }
}
Now here what happens is that if the parent Component sends new props the function checks if the prop.address is different from the state.address - this is the child Component state - and if it's different it's sets it to the value received from the props
Add this method in your Address class and it should work

Related

I can't call form.validateFields() with form.list - Ant Design

I want to call form.validateFields to validate when form.list remove But i can't
<Form.List name="formList">
{(fields, { add, remove }, { errors }) => (
<>
{fields.map(({ key, name, fieldKey, ...restField }) => (
<Form.Item
{...restField}
name={[name,"name"]}
fieldKey={[fieldKey,"fieldKey"]}
validateTrigger={["onChange", "onBlur", "onFocus"]}
// dependencies={[name]}
rules={[
{ required: true, message: "please enter text" },
{
pattern: new RegExp(/^[\x00-\x7F]+$/),
message: "please enter A-Z, a-z, 0-9"
},
({ getFieldValue }) => ({
validator(_, value) {
if (value) {
const values: string[] = getFieldValue("formList");
const valuesTmp = [...values];
const idx = valuesTmp.findIndex((e) => e === value);
valuesTmp.splice(idx, 1);
return valuesTmp.find((item:any) => item.name === value) ? Promise.reject("It's duplicated") : Promise.resolve();
}
return Promise.resolve();
},
}),
]}
>
<Input placeholder="Enter your name" />
</Form.Item>
<MinusCircleOutlined onClick={() => {
remove(name)
form.validateFields(['formList',0,'name']) // this i want to call validate for check duplicate again
}} />
))}
<Form.Item>
<Button type="dashed" onClick={() => add()} block icon={<PlusOutlined />}>
Add Token
</Button>
<Form.ErrorList errors={errors} />
</Form.Item>
</>
)}
</Form.List>
But when I press the remove button, the field is deleted but not validate again.
Ant Design tell me :
<Form.List name="users">
{fields =>
fields.map(field => (
<React.Fragment key={field.key}>
<Form.Item name={[field.name, 'name']} {...someRest1} />
<Form.Item name={[field.name, 'age']} {...someRest1} />
</React.Fragment>
))
}
</Form.List>
dependencies should be ['users',0,'name']
From https://ant.design/components/form/#API
You can use it like this:
form.validateFields([['formList',0,'name'], ['formList',1,'name']])
there is zero in your array but it just should be the form fields.
validateFields(['age','name'])
.then(values => {
console.log("something");
// do whatever you need to
/*
values:
{
username: 'username',
password: 'password',
}
*/
})
.catch(errorInfo => {
/*
errorInfo:
{
values: {
username: 'username',
password: 'password',
},
errorFields: [
{ name: ['password'], errors: ['Please input your Password!'] },
],
out-of-date: false,
}
*/
});

react hook form validation is not working after paste value

I created a model for a form which maps throught it to create form using react-hook-form
when i submit form for the first time, everything is Okay. but for the other times, when i paste a value into inputs, validation not work correctly(it shows required error but the input is not empty)
this is model:
export const formData = [
{
id: 1,
type: "text",
labelRequired: true,
label: "name",
shape: "inline",
placeholder: "name",
name: "nameOne",
validation: {
required: true,
minLength: 8,
},
size: 6,
},
{
id: 2,
type: "text",
labelRequired: true,
label: "family",
shape: "inline",
placeholder: "family",
name: "nameTwo",
validation: {
required: true,
minLength: 8,
},
size: 6,
},
{
id: 7,
type: "checkbox",
label: "Sample",
shape: "checkbox",
placeholder: "placeholder",
name: "checkbox_btn",
data: [
{
id: 41,
inputId: "inline-form-1",
label: "1",
},
],
size: 12,
},
];
the map method to create form based on model:
const Sample = () => {
const {
register,
handleSubmit,
formState: { errors },
reset,
} = useForm({
mode: "onBlur",
});
const submitHandler = (data, e) => {
e.target.reset();
console.log(data);
reset();
};
const mapForm = formData.map((item) => {
if (item.shape === "inline") {
return (
<InputContainer
key={item.id}
register={{
...register(item.name, {
required: item.validation.required,
minLength: item.validation.minLength,
}),
}}
validation={item.validation}
placeholder={item.placeholder}
label={item.label}
size={item.size}
error={errors[item.name]}
/>
);
}
if (item.shape === "checkbox") {
return (
<CheckBoxContainer
key={item.id}
label={item.label}
data={item.data}
register={{ ...register("medium", { required: true }) }}
error={errors.medium}
/>
);
}
});
return (
<Fragment>
<Breadcrumb parent="Dashboard" title="Default" />
<Container fluid={true}>
<Row>
<Col sm="12">
<Card>
<CardHeader>
<h5>Sample Card</h5>
</CardHeader>
<CardBody>
<Form onSubmit={handleSubmit(submitHandler)}>
<Row>{mapForm}</Row>
<Button type="submit" className="m-t-40">
Submit
</Button>
</Form>
</CardBody>
</Card>
</Col>
</Row>
</Container>
</Fragment>
);
};
export default Sample;
Also there are some container components for wrapping inputs like:
const InputContainer = ({
id,
register,
error,
label,
labelRequired,
size,
type,
placeholder,
validation,
}) => {
return (
<Col lg={size} style={{ marginTop: "-10px" }}>
<FormGroup>
<Label className={`col-form-label`}>
{label} {labelRequired && <span></span>}
</Label>
<Input
className="form-control"
type={type}
placeholder={placeholder}
{...register}
/>
{error && error.type === "required" && (
<p className="p-16 text-danger">this filed is required</p>
)}
</FormGroup>
</Col>
);
};
export default InputContainer;
I have not looked that deep into it to find out if this happens from a simple misuse of the useForm() hook, but here's what I've figured out.
According to the source code, register() returns the following interface (unrelated stuff omitted):
type UseFormRegisterReturn<...> = {
onChange: ChangeHandler;
onBlur: ChangeHandler;
ref: RefCallBack;
...
}
As you can see, this means only the onChange() and onBlur() events are being registered. onChange() is the one we're interested in.
After some quick testing, I've realized that for some unknown reason (maybe a browser bug? no idea), in certain conditions onChange() doesn't trigger when pasting text with CTRL+V.
Luckily, the regular onInput() event still triggers, so we can simply define this event using the register.onChange() handler:
<Input
className="form-control"
type={type}
placeholder={placeholder}
{...register}
onInput={register && register.onChange}
// TypeScript
// onInput={register?.onChange}
/>
If onInput() is already being used:
<Input
className="form-control"
type={type}
placeholder={placeholder}
{...register}
onInput={e => {
doOtherStuff(e);
if (register && register.onChange) {
register.onChange(e);
}
// TypeScript
// register?.onChange(e);
}
/>

React js - Save previous value in Ant Design Steps

I am using Ant Design Steps for my form but I am having a problem on how to save the value of the previous input.
Here is my code whole code:
import React from 'react';
import 'antd/dist/antd.css';
import './index.css';
import { Form, Icon, Input, Button, Steps } from 'antd';
const { Step } = Steps;
const steps = [
{
title: 'First',
content: 'First-content',
},
{
title: 'Second',
content: 'Second-content',
}
];
class NormalLoginForm extends React.Component {
constructor (props) {
super (props) ;
this.state = {
current: 0
}
}
next() {
const current = this.state.current + 1;
this.setState({ current });
}
prev() {
const current = this.state.current - 1;
this.setState({ current });
}
handleSubmit = e => {
e.preventDefault();
this.props.form.validateFields((err, values) => {
if (!err) {
console.log('Received values of form: ', values);
}
});
};
render() {
const { current } = this.state
const { getFieldDecorator } = this.props.form;
return (
<div>
<Steps current={current}>
{steps.map(item => (
<Step key={item.title} title={item.title} />
))}
</Steps>
<Form onSubmit={this.handleSubmit} className="login-form">
{current === 0 ? (
<Form.Item>
{getFieldDecorator('username', {
rules: [{ required: true, message: 'Please input your username!' }],
})(
<Input
prefix={<Icon type="user" style={{ color: 'rgba(0,0,0,.25)' }} />}
placeholder="Username"
/>,
)}
</Form.Item>
): ''}
{current === 1 ? (
<Form.Item>
{getFieldDecorator('password', {
rules: [{ required: true, message: 'Please input your Password!' }],
})(
<Input
prefix={<Icon type="lock" style={{ color: 'rgba(0,0,0,.25)' }} />}
type="password"
placeholder="Password"
/>,
)}
</Form.Item>
): ''}
</Form>
{current < steps.length - 1 && (
<Button type="primary" onClick={() => this.next()}>
Next
</Button>
)}
{current === steps.length - 1 && (
<Button type="primary" onClick={this.handleSubmit}>
Done
</Button>
)}
{current > 0 && (
<Button style={{ marginLeft: 8 }} onClick={() => this.prev()}>
Previous
</Button>
)}
</div>
);
}
}
What is happening is when I click next, the value of the previous input is gone. What I want to happen is when I click next the previous value will be save so when I click submit both of the values will be output in the console. The code comes from ant design and I used it for example
You should consider storing the data in a state :
constructor (props) {
super (props) ;
this.state = {
current: 0,
firstInput: '',
secondInput: '',
}
}
<Input
prefix={<Icon type="user" style={{ color: 'rgba(0,0,0,.25)' }} />}
placeholder="Username"
onChange={(e) => this.setState({firstInput: e.target.value})}
/>,
Then, in your submit press, you will be able to access the values of firstInput and secondInput by doing this.state.firstInput & this.state.secondInput.

TypeError: Cannot read property 'length' of undefined in React JS for country state dropdown

I'm trying to populate State based on selected Country.
I'm getting the error as shown below
The Service, Action and Reducer are working properly. I'm getting response from Action.
Below is the code
constructor(props) {
super(props)
this.state = {
CompanyName: '',
country:'',
statez:'',
selectedStateList: []
}
}
componentWillMount(){
this.props.actions.company.StateList();
}
handleSelect = (e) => {
this.setState({selectedCountry: e.target.value})
var filterStr = e.target.value == "1" ? 'Canada' : 'USA';
this.state.selectedStateList = this.props.stateList.length && this.props.stateList.filter(stateData => stateData.Country == filterStr)
}
render() {
return (
Form onSubmit={this.handleSubmit} className="gx-signin-form gx-form-row0">
<Row gutter={24}>
<Col span={12}>
<FormItem label="Business Name">
{getFieldDecorator('CompanyName', {
initialValue: this.state.CompanyName,
rules: [{
required: true, message: 'Please Input Your Business Name!',
}],
})(
<Input name='CompanyName' placeholder="Business Name"
onChange={(e) => {
e.preventDefault(); e.stopPropagation();
this.handleChange(e)
}}
/>
)}
</FormItem>
</Row>
<Row gutter={24}>
<Col span={12}>
<FormItem label="Business Address">
{getFieldDecorator('Address', {
initialValue: this.state.Address,
rules: [{
required: true, message: 'Please Input Business Address!',
}],
})(
<Input name='Address' placeholder="Business Address"
onChange={(e) => {
e.preventDefault(); e.stopPropagation();
this.handleChange(e)
}}
/>
)}
</FormItem>
</Col>
</Row>
<Row gutter={24}>
<Col span={12}>
<FormItem label="Country">
{getFieldDecorator('Country', {
initialValue: "",
rules: [{
//required: this.props.isEdit == false ? true : false, message: 'Please Select Your Country!',
}],
})(
<select style={{'width':'245px','height':'32px'}} onChange={this.handleSelect} >
<option value='0'>Select Country</option>
<option value='1'>Canada</option>
<option value='2'>USA</option>
</select>
)}
</FormItem>
</Col>
</Row>
<Row gutter={24}>
<Col span={12}>
<FormItem label="State">
{getFieldDecorator('State', {
initialValue: "",
rules: [{
/* required: this.props.isEdit == false ? true : false, message: 'Please Select Your State!', */
}],
})(
<select value={'StateID'} style={{'width':'245px','height':'32px'}}>
{this.state.selectedStateList.length && this.state.selectedStateList.map((value,index)=>(
<option value={value.StateID} key={index}>{value.StateName}</option>
))}
</select>
)}
</FormItem>
</Col>
<Row>
<Col span={24}>
<FormItem>
<Button type="primary" className="gx-mb-0" htmlType="submit">
Sign Up
</Button> Or Already Have One <Link to='/signin'> Sign In </Link>
</FormItem>
</Col>
</Row>
</Form>
)
}
const mapStateToProps = (state) => {
return {
stateList:state.companyReducer.stateList || []
}
};
const mapDispatchToProps = dispatch => ({
actions: {
company: bindActionCreators(companyAction, dispatch)
}
});
There is only one page for this puprpose.
How to change my code in order to avoid this error?
Is it anything with state and props?
Check like this
{this.state.selectedStateList && this.state.selectedStateList.length && this.state.selectedStateList.map((value,index)=>(
<option value={value.StateID} key={index}>{value.StateName}</option>
))}
and make sure you have correct values in the state
Also make sure you connect your component with mapStateToProps
Update
Try this in handleSelect
//this.setState({selectedCountry: e.target.value})
var filterStr = e.target.value == "1" ? 'Canada' : 'USA';
let selectedStateList = this.props.stateList.length &&
this.props.stateList.filter(stateData => stateData.Country == filterStr)
this.setState({selectedCountry: e.target.value, selectedStateList : selectedStateList });
when you do
this.setState({selectedCountry: e.target.value})
you erase everything you defined in constructor, I guees you should first prepare data, and then update whole state in 1 move:
handleSelect = (e) => {
const selectedStateList = this.props.stateList.filter(stateData => stateData.Country == filterStr)
this.setState({selectedCountry: e.target.value, selectedStateList});
}
and the last one, never set state directly like you did:
this.state.selectedStateList = .....

Unexpected token (8:8) while parsing file

I'm using antd and I wanna use its registration Form in my project.
Note: Before adding this component my project (registration.js) was working correctly and I've just copied and pasted the antd component.
Here is my registration.js file:
import { Form, Input, Tooltip, Icon, Cascader, Select, Row, Col, Checkbox, Button, AutoComplete } from 'antd';
const FormItem = Form.Item;
const Option = Select.Option;
const AutoCompleteOption = AutoComplete.Option;
class RegistrationForm extends React.Component {
state = {
confirmDirty: false,
autoCompleteResult: [],
};
handleSubmit = (e) => {
e.preventDefault();
this.props.form.validateFieldsAndScroll((err, values) => {
if (!err) {
console.log('Received values of form: ', values);
}
});
}
handleConfirmBlur = (e) => {
const value = e.target.value;
this.setState({ confirmDirty: this.state.confirmDirty || !!value });
}
compareToFirstPassword = (rule, value, callback) => {
const form = this.props.form;
if (value && value !== form.getFieldValue('password')) {
callback('Two passwords that you enter is inconsistent!');
} else {
callback();
}
}
validateToNextPassword = (rule, value, callback) => {
const form = this.props.form;
if (value && this.state.confirmDirty) {
form.validateFields(['confirm'], { force: true });
}
callback();
}
handleWebsiteChange = (value) => {
let autoCompleteResult;
if (!value) {
autoCompleteResult = [];
} else {
autoCompleteResult = ['.com', '.org', '.net'].map(domain => `${value}${domain}`);
}
this.setState({ autoCompleteResult });
}
render() {
const { getFieldDecorator } = this.props.form;
const { autoCompleteResult } = this.state;
const formItemLayout = {
labelCol: {
xs: { span: 24 },
sm: { span: 8 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 16 },
},
};
const tailFormItemLayout = {
wrapperCol: {
xs: {
span: 24,
offset: 0,
},
sm: {
span: 16,
offset: 8,
},
},
};
const prefixSelector = getFieldDecorator('prefix', {
initialValue: '86',
})(
<Select style={{ width: 70 }}>
<Option value="86">+86</Option>
<Option value="87">+87</Option>
</Select>
);
const websiteOptions = autoCompleteResult.map(website => (
<AutoCompleteOption key={website}>{website}</AutoCompleteOption>
));
return (
<Form onSubmit={this.handleSubmit}>
<FormItem
{...formItemLayout}
label="E-mail"
>
{getFieldDecorator('email', {
rules: [{
type: 'email', message: 'The input is not valid E-mail!',
}, {
required: true, message: 'Please input your E-mail!',
}],
})(
<Input />
)}
</FormItem>
<FormItem
{...formItemLayout}
label="Password"
>
{getFieldDecorator('password', {
rules: [{
required: true, message: 'Please input your password!',
}, {
validator: this.validateToNextPassword,
}],
})(
<Input type="password" />
)}
</FormItem>
<FormItem
{...formItemLayout}
label="Confirm Password"
>
{getFieldDecorator('confirm', {
rules: [{
required: true, message: 'Please confirm your password!',
}, {
validator: this.compareToFirstPassword,
}],
})(
<Input type="password" onBlur={this.handleConfirmBlur} />
)}
</FormItem>
<FormItem
{...formItemLayout}
label={(
<span>
Nickname
<Tooltip title="What do you want others to call you?">
<Icon type="question-circle-o" />
</Tooltip>
</span>
)}
>
{getFieldDecorator('nickname', {
rules: [{ required: true, message: 'Please input your nickname!', whitespace: true }],
})(
<Input />
)}
</FormItem>
<FormItem
{...formItemLayout}
label="Habitual Residence"
>
{getFieldDecorator('residence', {
initialValue: ['zhejiang', 'hangzhou', 'xihu'],
rules: [{ type: 'array', required: true, message: 'Please select your habitual residence!' }],
})(
<Cascader options={residences} />
)}
</FormItem>
<FormItem
{...formItemLayout}
label="Phone Number"
>
{getFieldDecorator('phone', {
rules: [{ required: true, message: 'Please input your phone number!' }],
})(
<Input addonBefore={prefixSelector} style={{ width: '100%' }} />
)}
</FormItem>
<FormItem
{...formItemLayout}
label="Website"
>
{getFieldDecorator('website', {
rules: [{ required: true, message: 'Please input website!' }],
})(
<AutoComplete
dataSource={websiteOptions}
onChange={this.handleWebsiteChange}
placeholder="website"
>
<Input />
</AutoComplete>
)}
</FormItem>
<FormItem
{...formItemLayout}
label="Captcha"
extra="We must make sure that your are a human."
>
<Row gutter={8}>
<Col span={12}>
{getFieldDecorator('captcha', {
rules: [{ required: true, message: 'Please input the captcha you got!' }],
})(
<Input />
)}
</Col>
<Col span={12}>
<Button>Get captcha</Button>
</Col>
</Row>
</FormItem>
<FormItem {...tailFormItemLayout}>
{getFieldDecorator('agreement', {
valuePropName: 'checked',
})(
<Checkbox>I have read the agreement</Checkbox>
)}
</FormItem>
<FormItem {...tailFormItemLayout}>
<Button type="primary" htmlType="submit">Register</Button>
</FormItem>
</Form>
);
}
}
const WrappedRegistrationForm = Form.create()(RegistrationForm);
ReactDOM.render(<WrappedRegistrationForm />, document.getElementById('main'));
And this is my index.html file:
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>React Project</title>
</head>
<body>
<div id="main"></div>
<script src="/build/bundle.js"></script>
</body>
</html>
I face with this error in my registration.js file:
Unexpected token (8:8) while parsing file
Line 8 refers to where we have state = {, how can I solve this problem?
Probably you are not using the right transpilers.
Declaring global variables in classes like your state = { ... } is only possible with ES7 (I believe). You are probably using a ES6 transpiler.
One fix would be changing your syntax to ES6. So you would have to declare you state like this:
class RegistrationForm extends React.Component {
constructor(props) {
super(props);
this.state = { ... };
}
// ...
}
ES6 also doesn't support declaring class methods with arrow syntax (myMethod = () => { ... }). You would have to change all of your methods to myMethod() { ... }
Another fix would be to download the right presets so babel (I'm guessing you are using babel) can transpile your ES7 syntax.

Resources