Reputation: 1297
I'm new to React & Redux so it is difficult for me to explain in plain English but I'll try my best. I have a parent/container component that forms the main 'page' of my app. In this component I am rendering a header and various fields like so:
What I want to achieve is for any user input in the title field to be reflected where it currently says 'Untitled Practice' in the header.
The parent component looks like this (excluding various imports for brevity):
export class DrillCreator extends Component {
render() {
return (
<div>
<EditHeader />
<div className="container-fluid max-width-container">
<InputWithTooltip
type={'text'}
placeholderText={'Title'}
tooltipText={'Title Tooltip'}
required
/>
<InputWithTooltip
type={'textarea'}
placeholderText={'Summary'}
tooltipText={'Summary Tooltip'}
/>
<InputWithTooltip
type={'file'}
placeholderText={'Hero Image/Video'}
tooltipText={'Hero Image/Video Tooltip'}
/>
<InputWithTooltip
type={'select'}
options={['7', '8', '9', '10']}
placeholderText={'Ages'}
tooltipText={'Ages Tooltip'}
required
/>
</div>
</div>
);
}
}
The <InputWithTooltip />
component is essentially a container that renders the appropriate input along with a tooltip component:
export default class InputWithTooltip extends Component {
constructor(props) {
super(props);
this.state = {
textEntered: '',
};
}
render() {
let input = null;
if (this.props.type === 'text') {
input = (
<TextInput
placeholderText={this.props.placeholderText}
updateText={textEntered => this.setState({ textEntered })}
/>
);
} else if (this.props.type === 'select') {
input = (
<SelectInput
placeholderText={this.props.placeholderText}
updateText={textEntered => this.setState({ textEntered })}
/>
);
} else if (this.props.type === 'textarea') {
input = (
<TextAreaInput
placeholderText={this.props.placeholderText}
updateText={textEntered => this.setState({ textEntered })}
/>
);
} else if (this.props.type === 'file') {
input = (
<FileInput
placeholderText={this.props.placeholderText}
updateText={textEntered => this.setState({ textEntered })}
/>
);
}
return (
<div>
<InputTooltip tooltipText={this.props.tooltipText} />
{input}
</div>
);
}
}
As you can see, I have a textEntered
state which is updated via an onChange
function passed via the updateText
props.
I have set up Redux so that I am able to call a dispatch function to set the title field in my reducer. This works fine if I simplify my parent component and simply call the <TextInput />
component which has the updateText
prop:
export class DrillCreator extends Component {
constructor() {
super();
this.state = {
textEntered: '',
};
}
render() {
return (
<TextInput
placeholderText="Title"
updateText={(textEntered) => {
this.setState({ textEntered });
this.props.setDrillTitleAction({ textEntered });
}}
/>
);
}
}
const mapDispatchToProps = dispatch => ({
setDrillTitleAction: drillCreator => dispatch(setDrillTitle(drillCreator)),
});
export default connect(null, mapDispatchToProps)(DrillCreator);
The issue I have is that I want to call setDrillTitleAction
from <InputWithTooltip />
instead of <TextInput />
as this is the only field in the form that I want to do anything special with.
Like I said I'm new to React and Redux so could be massively overcomplicating something or completely missing the point so any pointers would be massively helpful. Thanks.
Upvotes: 0
Views: 910
Reputation: 330
You can pass the dispatch function from the container component in as a prop to the display component, and then call it when the value is changed.
In your case you need to pass setTitleDrillAction
in as a prop to InputWithTooltip
and then call if from within your updateText
callbacks.
One thing to point out is that you will be storing the text box value multiple times - on the redux state and the InputWithTooltip
state. You might choose to just make InputWithTooltip
a stateless component which receives its value as a prop and dispatches updates to redux (via its parent container as described above).
Upvotes: 2