Reputation: 65
I want to hide/show some tabs in a different file. We have a modal with tabs, and some of the tabs should hide while clicking on radio buttons from another file which is another component. I mean that those components is in different files.
My question is how do I pass data or functions from one file to another file? I will need to do this with my onChange for the radio buttons. I am using the Tabs from react-bootstrap.
I hope some of you know some examples of how to do it?
Thanks in advance! :)
EDIT:
In tabs.js
export default class ArchiveForm extends React.Component<Props, State> {
static defaultProps = {
onChange() {}
};
constructor(props) {
super(props);
// Bindings
this.handleTabChange = this.handleTabChange.bind(this);
// Child refs
this.childrenForms = {};
this.state = {
key: 1
};
}
handleTabChange(key) {
this.setState({key});
}
handleHideTabs(key) {
const {data} = this.props;
if (data.Type === 0) {
this.change = key === 2 && 3;
}
}
render() {
const {data, archive, groups, users} = this.props;
const {key} = this.state;
console.log('markers tab', data);
if (data.Type === 0) {
this.change = false;
} else {
this.change = true;
}
return (
<Tabs
activeKey={key}
onSelect={this.handleTabChange}
id="workflow-edit-form"
bsStyle="pills"
animation={false}
>
<Tab eventKey={1} title="General">
<Row>
<Col sm={6}>
<Identification
{...data}
ref={instance => { this.childrenForms.Identifications = instance; }}
change={event => this.handleHideTabs(event)}
/>
<Condition
{...data}
ref={instance => { this.childrenForms.Conditions = instance; }}
/>
</Col>
<Col sm={6}>
<Display
{...data}
ref={instance => { this.childrenForms.Displays = instance; }}
/>
</Col>
</Row>
</Tab>
{this.change && (
<Tab eventKey={2} title="Action">
<Row>
<Col sm={12}>
<Action
{...data.Action}
ref={instance => { this.childrenForms.Actions = instance; }}
/>
</Col>
</Row>
</Tab>)}
{this.change && (
<Tab eventKey={3} title="Notification">
<Row>
<Col sm={6}>
<Notification
{...data.NotificationSettings}
ref={instance => { this.childrenForms.Notifications = instance; }}
/>
</Col>
</Row>
</Tab>)}
<Tab eventKey={4} title="Archive filter">
<Row>
<Col sm={12}>
{/* <ArchiveFilter
{...data.ArchiveFilter}
archive={archive}
ref={instance => { this.childrenForms.ArchiveFilters = instance; }}
/> */}
</Col>
</Row>
</Tab>
<Tab eventKey={5} title="Access list">
<Row>
<Col sm={12}>
<AccessList
properties={data.AccessList.Members}
groups={groups}
users={users}
ref={instance => { this.childrenForms.MemberList = instance; }}
/>
</Col>
</Row>
</Tab>
</Tabs>
);
}
}
In the file where the radio button is. Identification.js
export default class extends React.Component<Props, State> {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.handleRadioChange = this.handleRadioChange.bind(this);
const {Name, Description, Type, Modes, DisplayType, Position} = props;
this.state = {Name, Description, Type, Modes, DisplayType, Position};
this.translations = {
identification: LocalizationService.get('userManagement', 'identification'),
name: LocalizationService.get('userManagement', 'name'),
description: LocalizationService.get('userManagement', 'description'),
type: LocalizationService.get('management', 'type'),
standard: LocalizationService.get('management', 'standard'),
extended: LocalizationService.get('management', 'extended')
};
}
handleChange(e) {
this.setState({
[e.target.dataset.name]: e.target.value
});
}
handleRadioChange(e) {
this.setState({
Type: parseInt(e.target.value, 10)
});
}
render() {
const {Name, Description, Type} = this.state;
return (
<form className="modal-container">
<h4>{this.translations.identification}</h4>
<FormGroup>
<ControlLabel className="input-label">{this.translations.name}</ControlLabel>
<FormControl
className="modal-inputs"
placeholder="Name"
type="text"
value={Name}
data-name="Name"
onChange={this.handleChange}
/>
</FormGroup>
<FormGroup>
<ControlLabel className="input-label">{this.translations.description}</ControlLabel>
<FormControl
className="modal-inputs"
placeholder="Description"
type="text"
value={Description}
data-name="Description"
onChange={this.handleChange}
/>
</FormGroup>
<ControlLabel className="input-label">
{this.translations.type}
</ControlLabel>
<FormGroup className="condition-radio-buttons">
<Radio name="radioGroup10" defaultChecked={Type === 0} value={0} onChange={props.change}>
{this.translations.standard}
</Radio>
{' '}
<Radio name="radioGroup10" defaultChecked={Type === 1} value={1} onChange={this.handleRadioChange}>
{this.translations.extended}
</Radio>
</FormGroup>
</form>
);
}
}
And yes I get my data from API! :)
Upvotes: 3
Views: 7157
Reputation: 21
This issue I have solved using tabClassName='d-none'.
<Tabs defaultActiveKey="text" id="text">
<Tab eventKey="text" tabClassName={!this.state.visual ? 'd-none' :
''} title="Text">
<Text user={this.state.id} getPostLength={this.getPostLength} />
</Tab>
<Tab eventKey="visual" tabClassName={!this.state.visual ? 'd-none' :
''} title="Visual">
<Visual user={this.state.id} getPostLength={this.getPostLength} />
</Tab>
<Tab eventKey="video" tabClassName={!this.state.video ? 'd-none' :
''} title="Video">
<Video user={this.state.id} getPostLength={this.getPostLength} />
</Tab>
<Tab eventKey="audio" title="Audio">
<Audio user={this.state.id} tabClassName={!this.state.audio ? 'd-
none' : ''} getPostLength={this.getPostLength} />
</Tab>
</Tabs>
Upvotes: 2
Reputation: 1180
The issue you have come across is normal and everyone runs into it at some point during a projects development cycle.
One of the possible solutions would be to move the state up to a component that's a parent of both of the components that need to share the data, and then pass the state down as a prop to both components.
If that's an ugly solution for you, your best option is to use a state management library. The most popular ones are Redux and MobX
Upvotes: 2