Reputation: 6166
There are two components which don't have parent-child or sibling relationship between them.
One of them build the Toolbar and another one contains a color picker. The idea is to change the color of the Toolbar based on the value set in the color picker.
Here is my code so far:
import React from 'react';
import { Button, Icon } from 'semantic-ui-react';
import { ChromePicker } from 'react-color';
export default class Banner extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
displayColorPicker: false,
background: '#fff',
};
}
handleClick = () => {
this.setState({ displayColorPicker: true });
};
handleClose = () => {
this.setState({ displayColorPicker: false });
};
handleChange = color => {
this.setState({ background: color.hex });
};
handleChangeComplete = color => {
this.setState({ background: color.hex });
};
render() {
const popover = {
position: 'absolute',
zIndex: '2',
};
const cover = {
position: 'fixed',
top: '0px',
right: '0px',
bottom: '0px',
left: '0px',
};
return (
<div className="banner-container settings-banner">
<table className="settings-banner-container">
<tbody>
<tr className="setttings-container-tr">
<div
className="xx"
style={{ backgroundColor: this.state.background }}>
<div className="title-cell-value settings-banner-title">
Brand color
</div>
<div>
<Button onClick={this.handleClick}>Pick Color</Button>
{this.state.displayColorPicker ? (
<div style={popover}>
<div
style={cover}
onClick={this.handleClose}
onKeyDown={this.handleClick}
role="button"
tabIndex="0"
aria-label="Save"
/>
<ChromePicker
color={this.state.background}
onChange={this.handleChange}
onChangeComplete={this.handleChangeComplete}
/>
</div>
) : null}
</div>
</div>
</tr>
</tbody>
</table>
</div>
);
}
}
In the above file, the ChromePicker is used to choose a color and save its value in this.state.background
. I'm using that value to update the color of div with class xx
. This works good, the div's color is updated directly.
However, I don't know how to "export" that color value outside and use it in another component.
In this case it would be the Toolbar, I want to send the value from this.state.background
to the style = {{ .. }}
Is there a way to do it?
import React from 'react';
import Logo from '../Logo/Logo';
export default class Toolbar extends React.PureComponent {
render() {
return (
<div className="corporate-toolbar" style={{ backgroundColor: 'green' }}>
<Logo corporate />
</div>
);
}
}
Upvotes: 0
Views: 1563
Reputation: 39260
Here is a working example using context:
//in file ColorContext.js (should export but breaks snippet)
const ColorContext = React.createContext();
const ColorProvider = ({ children }) => {
const [color, setColor] = React.useState('#fff');
return (
<ColorContext.Provider value={{ color, setColor }}>
{children}
</ColorContext.Provider>
);
};
//in file Banner.js
class Banner extends React.PureComponent {
handleChange = (color) => {
this.context.setColor(color);
};
render() {
return (
<div style={{ backgroundColor: this.context.color }}>
<select
value={this.context.color}
onChange={(e) =>
this.handleChange(e.target.value)
}
>
<option value="#fff">fff</option>
<option value="#f00">f00</option>
<option value="#f0f">f0f</option>
</select>
</div>
);
}
}
//ColorContext is imported from ColorContext.js
Banner.contextType = ColorContext;
//in file Toolbar.js
class Toolbar extends React.PureComponent {
render() {
return (
<h1 style={{ backgroundColor: this.context.color }}>
Toolbar
</h1>
);
}
}
//ColorContext is imported from ColorContext.js
Toolbar.contextType = ColorContext;
const App = () => (
<div>
<Banner />
<Toolbar />
</div>
);
ReactDOM.render(
<ColorProvider>
<App />
</ColorProvider>,
document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Upvotes: 1
Reputation: 558
There is many ways to do it
You can use context
(best solution), redux
(if you app is really big) or just move the property to the common parent
and pass it to components (it's the worst way, not recommended)
Documentation for context - https://reactjs.org/docs/context.html
Documentation for redux - https://react-redux.js.org
A simple example of using context https://www.digitalocean.com/community/tutorials/react-usecontext
Upvotes: 1