How to pass a props from parent to child css properties? - javascript

I have a parent and child component there is a button in parent component on Clicking that button it should send a Props -"red" so the child should receive the red and change its background color as red. Below my code is there
jsfiddle.net/t1ru6oyz/3/
Child
import React from "react";
import ReactDOM from "react-dom";
const childContainer = {
border: "0px solid #000",
width: "300px",
height: "300px",
textAlign: "middle",
margin: "0 auto",
marginTop: "60px"
};
const Child = props => {
return (
<div
style={{
backgroundColor: props.color
}}
/>
);
};
export default Child;
Parent
import React, { Component } from "react";
import "./App.css";
import Child from "./child";
const parentContainer = {
border: "10px solid #000",
width: "500px",
height: "500px",
margin: "20px",
textAlign: "middle"
};
class App extends Component {
constructor() {
super();
this.state = {
currentColor: "red"
};
}
componentDidMount() {
this.setState({
currectColor: "green"
});
}
changeColor = () => {
this.setState({
currectColor: "blue"
});
};
render() {
console.log("in render", this.state);
return (
<div style={parentContainer}>
<button onClick={this.changeColor}>Blue</button>
<p>{this.state.name}</p>
<Child color={this.state.currentColor} />
</div>
);
}
}
export default App;

You have a few typos there in your parent component like currectColor, just fix those first. Then, you can add the backgroundColor property to your childContainer if there is prop by checking it.
const parentContainer = {
border: "10px solid #000",
width: "500px",
height: "500px",
margin: "20px",
textAlign: "middle"
};
class App extends React.Component {
constructor() {
super();
this.state = {
currentColor: "red"
};
}
componentDidMount() {
this.setState({
currentColor: "green"
});
}
changeColor = () => {
this.setState({
currentColor: "blue"
});
};
render() {
return (
<div style={parentContainer}>
<button onClick={this.changeColor}>Blue</button>
<p>{this.state.name}</p>
<Child color={this.state.currentColor} />
</div>
);
}
}
const Child = props => {
let childContainer = {
border: "0px solid #000",
width: "300px",
height: "300px",
textAlign: "middle",
margin: "0 auto",
marginTop: "60px"
};
if ( props.color ) {
childContainer = { ...childContainer, backgroundColor: props.color }
}
return (
<div
style={childContainer}
/>
);
};
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

I have created my own components, but you can apply this logic.
class Child extends React.Component {
constructor(props) {
super(props);
}
render() {
return ( <
h1 style = {
{
backgroundColor: this.props.color
}
} > hello < /h1>
)
}
}
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {
color: ''
}
}
handleClick = () => {
this.setState({
color: 'red'
})
}
render() {
return ( <
div >
<
Child color = {
this.state.color
}
/> <
button onClick = {
this.handleClick
} > change Child color < /button> < /
div >
)
}
}
ReactDOM.render( <
Parent / > ,
document.getElementById("root")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

You need change in App component. Keep currentColor to blue and change it to red in changeColor function but you are doing it in reverse
Try with below code
const parentContainer = {
border: "10px solid #000",
width: "500px",
height: "500px",
margin: "20px",
textAlign: "middle"
};
class App extends Component {
constructor() {
super();
this.state = {
currentColor: "blue"
};
}
componentDidMount() {
this.setState({
currentColor: "green"
});
}
changeColor = () => {
this.setState({
currentColor: "red"
});
};
render() {
console.log("in render", this.state);
return (
<div style={parentContainer}>
<button onClick={this.changeColor}>Blue</button>
<p>{this.state.name}</p>
<Child color={this.state.currentColor} />
</div>
);
}
}
export default App;

Related

How to change css code by pressing a button

Goal:
When you press on the button 'ok', the id element named test2 should be display non and id element named test1 should be display block with support of css code.
And also please take account to the color of the text that is located in the css code.
Problem:
I don't know how to solve it.
What is needed to be changed in the source code in order to achieve the goal?
Stackblitz:
https://stackblitz.com/edit/react-modal-gdh4hp?
Info:
*I'm newbie in Reactjs
Thank you!
index.js
import React, { Component } from 'react';
import { render } from 'react-dom';
import { Modal } from './modal';
import './style.css';
class App extends Component {
constructor() {
super();
this.state = {
modal: true
};
}
handleCloseModal = () => {
alert('ddd');
};
render() {
const { modal } = this.state;
const non = {
display: 'none',
color: 'yellow'
};
const block = {
display: 'block',
color: 'yellow'
};
return (
<div>
{modal ? (
<Modal
onClose={() => {
this.setState({ modal: false });
}}
>
<div id="test1" style={non}>Awesome1</div>
<div id="test2">Awesome2</div>
<button onClick={() => this.handleCloseModal()}>ok</button>
</Modal>
) : (
<button
onClick={() => {
this.setState({ modal: true });
}}
>
Show modal
</button>
)}
</div>
);
}
}
render(<App />, document.getElementById('root'));
modal.js
import React from 'react';
export class Modal extends React.Component {
render() {
const { children, onClose } = this.props;
return (
<div style={{position: "absolute", top: 0, left: 0, width: "100%", height: "100%", background: "gray"}} onClick={ev => onClose()}>
<div
style={{margin: "auto", background: "white", border: "red", width: "500px", height: "300px"}}
onClick={ev => ev.stopPropagation()}>
{ children }
</div>
</div>
);
}
}
You can simply do that :
ok() => {
document.getElementById('test1').style.display = 'block'
document.getElementById('test2').style.display = 'none'
}
You can use state
class App extends Component {
constructor() {
super();
this.state = {
modal: true,
showBlock: "",
showNon: "",
color: ""
};
}
handleCloseModal = () => {
this.setState({showBlock: "block"});
this.setState({showNon: "none"});
this.setState({color: "yellow"});
alert('ddd');
};
render() {
const { modal } = this.state;
return (
<div>
{modal ? (
<Modal
onClose={() => {
this.setState({ modal: false });
}}
>
<div id="test1" style={{display: this.state.showBlock, color: this.state.color}}>Awesome1</div>
<div id="test2" style={{display: this.state.showNon, color: this.state.color}}>Awesome2</div>
<button onClick={() => this.handleCloseModal()}>ok</button>
</Modal>
) : (
<button
onClick={() => {
this.setState({ modal: true });
}}
>
Show modal
</button>
)}
</div>
);
}
}
render(<App />, document.getElementById('root'));
React way to achieve that is to use useRef hook (or createRef for class approach):
Class approach:
constructor(props) {
this.testRef = React.createRef()
}
const toggleBlock = () => {
testRef.current.style.display = 'block'
testRef.current.style.color = 'yellow'
}
render() {
return (
<>
<div id="test1" ref={testRef}>Awesome1</div>
<button onclick={this.toggleBlock}>Ok</button>
</>
)
}
Hooks approach:
const testRef = useRef(null)
const toggleBlock = () => {
testRef.current.style.display = 'block'
testRef.current.style.color = 'yellow'
}
return (
<>
<div id="test1" ref={testRef}>Awesome1</div>
<button onclick={this.toggleBlock}>Ok</button>
</>
)

Problem with array of refs to reference a particular column

I can't get refs working. I want to render several columns and then render items that are placed over the right column. For example, declared items: const items = [0, 2, 5] should be rendered over the grid like that (assuming that first column has index 0):
I want to use refs on columns for getting column positions (using getBoundingClientRect() just for the idea) but my columnsRefs[index].current is null even though refs are assigned in componentDidMount as it's recommended. Here is my code:
import * as React from 'react';
export const GridColumn = (props: {forwardedRef?: any }) => (
<div style={{borderRight: "1px solid #ababab", width: "20px", height: "200px"}} ref={props.forwardedRef}></div>
);
interface GridProps {
}
export class Grid extends React.Component<GridProps, any> {
public constructor(props: GridProps) {
super(props);
this.state = {
columns: []
}
}
private columnRefs = new Array<React.RefObject<HTMLDivElement>>();
public componentDidMount(){
// setup the columns with refs
const columnIds = [0, 1, 2, 3, 4, 5, 6, 7];
const columns = columnIds.map(id => {
const ref = React.createRef<HTMLDivElement>();
this.columnRefs.push(ref);
return (<GridColumn forwardedRef={ref}/>)
});
this.setState({columns: columns});
}
public render() {
// setup the items
const items = [
0, 2, 5
]
let elements = items.map(item => {
if(this.columnRefs[item] && this.columnRefs[item].current) {
return (
<div style={{backgroundColor: "blue",
opacity: 0.5,
position: "absolute",
width: "10px",
height: "20px",
left: `${this.columnRefs[item].current.getBoundingClientRect().left}px`,
top: "0"}}>
</div>);
}
else {
return undefined;
}
});
return (
<div style={{width: "500px", height: "200px", position: "relative"}}>
{elements}
<div style={{display: "flex"}}>
{this.state.columns}
</div>
</div>);
}
}
What do I do wrong so that the condition in render if(this.columnRefs[item] && this.columnRefs[item].current) is all the time false?
You should not store your rendered components in state. State is for data you want to transform into markup. Here is modified code with annotations:
// Now component properly forwards ref
const GridColumn = React.forwardRef((props, ref) => (
<div
style={{ borderRight: "1px solid #ababab", width: "20px", height: "200px" }}
ref={ref}
{...props}
></div>
));
class Grid extends React.Component {
constructor(props) {
super(props);
this.state = {
columns: [1,2,3,4,5,6,7,8,9],
rendered: false
};
}
// When you want to use collection of refs, you can set up your own storage for them
// I use Set because it will prevent duplicates
// It is important that when component will be removed it's ref will turn into `null`, so you will have to check if your div still exists
columnRefs = new Set();
componentDidUpdate() {
// you will see your refs set in console on each render
console.debug(this.columnRefs);
}
componentDidMount() {
// You need to rerender to render something from refs
this.setState({rendered: true});
}
render() {
const items = [0, 2, 5];
let elements = items.map((item) => {
// turn set into array and filter out null
let refArray = [...this.columnRefs].filter(Boolean);
if (refArray[item]) {
return (
<div
key={item}
style={{
backgroundColor: "blue",
opacity: 0.5,
position: "absolute",
width: "10px",
height: "20px",
left: `${refArray[item].getBoundingClientRect().left}px`,
top: "0",
}}
></div>
);
} else {
return undefined;
}
});
return (
<div style={{ width: "500px", height: "200px", position: "relative" }}>
{elements}
<div style={{ display: "flex" }}>
{/* We use here ref callback to store forwarded ref into out set */}
{this.state.columns.map((item) => (
<GridColumn key={item} ref={(ref) => this.columnRefs.add(ref)} />
))}
</div>
</div>
);
}
}
What to read:
callback refs
forwarding refs
Set
Example
Reproducible and partially fixed example: https://jsfiddle.net/moL1sbzj/
I'm not sure if refs are needed at all
Use left:
left: item * 20 + 'px',
it's cheaper than .current.getBoundingClientRect().left
result:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
</head>
<body>
<div id="root"></div>
<script src="https://unpkg.com/react#17/umd/react.development.js" crossorigin ></script>
<script src="https://unpkg.com/react-dom#17/umd/react-dom.development.js" crossorigin ></script>
<script src="https://unpkg.com/babel-standalone#6/babel.min.js"></script>
<script type="text/babel">
const {useEffect, Fragment, useState} = React;
const GridColumn = (props) => (
<div
style={{ borderRight: "1px solid #ababab", width: "20px", height: "200px" }}
{...props}
></div>
);
class Grid extends React.Component {
constructor(props) {
super(props);
this.state = {
columns: [1, 2, 3, 4, 5, 6, 7, 8, 9],
rendered: false
};
}
componentDidUpdate() {
// you will see your refs set in console on each render
// console.debug(this.columnRefs);
}
componentDidMount() {
// You need to rerender to render something from refs
this.setState({ rendered: true });
}
render() {
const items = [0, 2, 5];
return (
<div
style={{
width: "500px",
height: "200px",
position: "relative"
}}
>
<div style={{ display: "flex" }}>
{this.state.columns.map((item, index) => (
<GridColumn key={item}>
{items.includes(index) && (
<div
style={{
backgroundColor: "blue",
opacity: 0.5,
width: "10px",
height: "20px"
}}
></div>
)}
</GridColumn>
))}
</div>
</div>
);
}
}
ReactDOM.render(<Grid />, document.getElementById("root"));
</script>
</body>
</html>
Multicolumn example:
getWidth function was added for calculate fill (width):
getWidth = (arr, index) => {
return arr.includes(index + 1) ? 20 : 10;
};
using this:
width: this.getWidth(items, index) + "px",
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
</head>
<body>
<div id="root"></div>
<script src="https://unpkg.com/react#17/umd/react.development.js" crossorigin ></script>
<script src="https://unpkg.com/react-dom#17/umd/react-dom.development.js" crossorigin ></script>
<script src="https://unpkg.com/babel-standalone#6/babel.min.js"></script>
<script type="text/babel">
const {useEffect, Fragment, useState} = React;
const GridColumn = (props) => (
<div
style={{ borderRight: "1px solid #ababab", width: "20px", height: "200px" }}
{...props}
></div>
);
class Grid extends React.Component {
constructor(props) {
super(props);
this.state = {
columns: [1, 2, 3, 4, 5, 6, 7, 8, 9],
rendered: false
};
}
componentDidUpdate() {
// you will see your refs set in console on each render
// console.debug(this.columnRefs);
}
componentDidMount() {
// You need to rerender to render something from refs
this.setState({ rendered: true });
}
getWidth = (arr, index) => {
return arr.includes(index + 1) ? 20 : 10;
};
render() {
const items = [0,1, 2, 5];
return (
<div
style={{
width: "500px",
height: "200px",
position: "relative"
}}
>
<div style={{ display: "flex" }}>
{this.state.columns.map((item, index) => (
<GridColumn key={item}>
{items.includes(index) && (
<div
style={{
backgroundColor: "blue",
opacity: 0.5,
width: this.getWidth(items, index) + "px",
height: "20px"
}}
></div>
)}
</GridColumn>
))}
</div>
</div>
);
}
}
ReactDOM.render(<Grid />, document.getElementById("root"));
</script>
</body>
</html>
for achieve this effect (no vertical lines) use style:
.afterFull::after {
content: "";
display: block;
position: relative;
left: 1px;
height: 20px;
border-right: 1px solid;
border-color: var(--color);
}
in code:
<div
className="afterFull"
style={{
backgroundColor: "blue",
opacity: 0.5,
width: this.getWidth(items, index) + 0 + "px",
height: "20px",
"--color": "rgba(0, 0, 255, 0.5)"
}}
/>

how to return components within paths? (syntax errors)

There are syntax errors in the return of the components so the app doesn't work (not render in the browser), how to return components within paths?
the problem is here (return App):
<Route exact path='/' component={()=>{ return <Addroom {
<button onClick={add=this.create}>Create</button>}/>}}/>
<Route exact path='/room' component={()=>{this.state.roomsList.map((element, key) => {
return (
<Room
id={key + 1}
key={key}
r={element.room}
rt={element.roomType}
ct={element.colorType}
sr={element.boxColor}
/>
);
})}}/>
I share all the components to help understanding:
App.js:
import React, { Component } from "react";
// import 'bootstrap/dist/css/bootstrap.min.css'
// import './App.css';
import Addroom from "./components/Addroom.js";
import Room from "./components/Room.js";
import {BrowserRouter as Router,Switch,Route,Link} from 'react-router-dom';
import 'bootstrap/dist/css/bootstrap.min.css';
export default class App extends Component {
state = {
roomsList: []
};
create = r => {
this.setState({
roomsList: [...this.state.roomsList, r],
});
};
render() {
return (
<div className="backGroundMain" style={{backgroundColor: "lightseagreen", height: "600px", width: "850px"}}>
<h1 style={{backgroundColor: "aquamarine", height: "40px", width: "270px", borderRadius: "5px", border: "2px", margin: "15px"}} >My Smart House</h1>
<Router>
<div className="row">
<div className="col-6"><Link to='/room'>My Rooms</Link></div>
<div className="col-6"><Link to='/'>Create Room</Link></div>
</div>
<Switch>
<Route exact path='/' component={()=>{ return <Addroom {
<button style={{backgroundColor: "aquamarine", height: "20px", width: "60px", borderRadius: "5px", border: "2px"}} onClick={add=this.create}>Create</button>}/>}}/>
<Route exact path='/room' component={()=>{this.state.roomsList.map((element, key) => {
return (
<Room
id={key + 1}
key={key}
r={element.room}
rt={element.roomType}
ct={element.colorType}
sr={element.boxColor}
/>
);
})}}/>
</Switch>
</Router>
</div>
);
}
}
Room.js:
import React, { Component } from "react";
export default class Room extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
const { id, r, rt, ct, sr } = this.props;
return (
<div className="Box" style={{backgroundColor: sr, height: "170px", width: "170px", margin: "30px"}}>
<h3>
Room {id}: {r}{" "}
</h3>
<h3>
Room Type {id}: {rt}
</h3>
<h3>
Room Color {id}: {ct}
</h3>
</div>
);
}
}
Addroom.js:
import React, { Component } from "react";
export default class Addroom extends Component {
constructor(props) {
super(props);
this.state = {
roomNameInputColor: "white",
roomTypes: ["kitchen", "bathroom", "bedroom"],
roomSelected: "kitchen",
colorTypes: ["red", "green", "blue", "teal", "mediumblue", "mediumorchid", "wheat", "Steelblue"],
colorSelected: "red"
};
}
addRoomName = e => {
const room = e.target.value;
let roomNameInputColor = "white";
if (e.target.value.length >= 5) {
roomNameInputColor = "green";
} else {
roomNameInputColor = "red";
}
this.setState({ room, addRoomName: room, roomNameInputColor });
};
createRoom = () => {
this.props.add({
room: this.state.room,
roomType: this.state.roomSelected,
colorType: this.state.colorSelected,
boxColor: this.state.colorSelected
});
};
createRoomType = () => {
this.props.addRoomType(this.state.roomSelected);
};
createColorType = () => {
this.props.addColorType(this.state.colorSelected);
};
createBoxColor = () => {
this.props.colorTheBox(this.state.colorSelected);
};
setCategory = roomSel => {
this.setState({ roomSelected: roomSel });
};
setColorCategory = colorSel => {
this.setState({ colorSelected: colorSel });
};
render() {
return (
<div className="backGroundAddRoom" style={{backgroundColor: "mediumaquamarine", height: "93px", width: "200px", margin: "15px"}}>
{/* //Select Room Type */}
<select onChange={e => this.setCategory(e.target.value)}>
{this.state.roomTypes.map((type, key) => (
<option key={key} value={type}>
{type}
</option>
))}
</select>
<br />
{/* //Select Room Color */}
<select onChange={e => this.setColorCategory(e.target.value)}>
{this.state.colorTypes.map((type, key) => (
<option key={key} value={type}>
{type}
</option>
))}
</select>
<br />
<input
onChange={this.addRoomName}
style={{ backgroundColor: this.state.roomNameInputColor }}
placeholder="Name Your Room"
/>
<br />
<button style={{backgroundColor: "aquamarine", height: "20px", width: "60px", borderRadius: "5px", border: "2px"}}
onClick={this.createRoom}>Create</button>
</div>
);
}
}
this.state.roomsList.map((element, key) => {
return (
<Room
id={key + 1}
key={key}
r={element.room}
rt={element.roomType}
ct={element.colorType}
sr={element.boxColor}
/>
);
})
Put above map in one single component and then use
<Route exact path='/room' component={RoomListComponent}/>

React component auto-remounted on state update, why?

I have a parent React.js component, passing a state and a setter to a child component.
Every time the child component use the setter, the child component is unmounted & remounted.
I'm new to react and I don't understand what is happening.
const useState = React.useState;
class MyComponnent extends React.Component {
intervalID = null;
componentDidMount() {
console.log("MOUNTING");
this.intervalID = setInterval(() => {
this.props.setA({ a: this.props.a.a + 1 });
}, 1000);
}
componentWillUnmount() {
clearInterval(this.intervalID);
}
render = () => {
return (
<div
style={{
display: "flex",
alignItems: "center",
justifyContent: "center",
flexDirection: "column"
}}
>
<div
style={{
flexDirection: "row",
display: "flex",
justifyContent: "center",
alignItems: "center",
marginTop: "30px"
}}
>
{this.props.a.a}
</div>
</div>
);
};
}
function App() {
const [activeStep] = useState(0);
const [a, setA] = useState({ a: 0 });
// eslint-disable-next-line react/no-multi-comp
function StepPage() {
if (0 === 0) {
return <MyComponnent a={a} setA={setA} />;
} else {
return <MyComponnent />;
}
}
return (
<div>
<StepPage />
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
.App {
font-family: sans-serif;
text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js"></script>
<div id="root"></div>
The problem is that your are creating a new instance of your component by defining StepPage inside a render function.
You can refactor your StepPage component so it will be defined outside of render method,
function StepPage({ setA, a}) {
if (0 === 0) {
return <MyComponnent a={a} setA={setA} />;
} else {
return <MyComponnent />;
}
}
export default function App() {
const [activeStep] = useState(0);
const [a, setA] = useState({ a: 0 });
return (
<div>
<StepPage a={a} setA={setA} />
</div>
);
}
StepPage in your example is re-defined every time App renders.
Calling the function normally instead of using it as a React component alleviates the issue:
return (
<div>
{StepPage()}
</div>
);
const useState = React.useState;
class MyComponnent extends React.Component {
intervalID = null;
componentDidMount() {
console.log("MOUNTING");
this.intervalID = setInterval(() => {
this.props.setA({ a: this.props.a.a + 1 });
}, 1000);
}
componentWillUnmount() {
clearInterval(this.intervalID);
}
render = () => {
return (
<div
style={{
display: "flex",
alignItems: "center",
justifyContent: "center",
flexDirection: "column"
}}
>
<div
style={{
flexDirection: "row",
display: "flex",
justifyContent: "center",
alignItems: "center",
marginTop: "30px"
}}
>
{this.props.a.a}
</div>
</div>
);
};
}
function App() {
const [activeStep] = useState(0);
const [a, setA] = useState({ a: 0 });
// eslint-disable-next-line react/no-multi-comp
function StepPage() {
if (0 === 0) {
return <MyComponnent a={a} setA={setA} />;
} else {
return <MyComponnent />;
}
}
return (
<div>
{StepPage()}
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
.App {
font-family: sans-serif;
text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js"></script>
<div id="root"></div>

Elements (React Components) with position: relative overlapping

tl;dr: I'm finding that consecutive elements on my page with position: relative are overlapping, and really don't understand why.
Details: I'm trying to write a re-usable React component SlidePair that allows you to toggle between two other components with a slide animation, passing data between them. I'm using react-reveal for the animation, and positioning the elements at the same place in the page, so the exit of one accompanies the entry of the other. To make the divs overlap I followed the approach of this SO question.
My code, in the context of an App.js file from create-react-app, is below. You see that in the main App component I want to stack two SlidePair elements, which turn out to overlap instead. Everything else are just some example components for me to plug in; I've only included them for the sake of anyone who just wants to copy and paste the whole thing to get it running.
import React, {Component} from 'react';
import Slide from 'react-reveal/Slide';
class RedBox extends Component {
constructor(props){
super(props);
this.handleChange = this.handleChange.bind(this);
this.state = {
text: props.text
}
}
handleChange(event) {
this.setState({text: event.target.value});
}
render(){
const { toggleState, text, style} = this.props;
return(
<div style={style}
onClick={()=>{console.log('red clicked'); toggleState({text: this.state.text})}}>
<input onChange={this.handleChange}
type="text" value={this.state.text}
onClick={(event)=>{event.stopPropagation()}}
style={{zIndex: '999'}}
/>
{ text }
</div>
);
}
}
const BlueBox = ({toggleState, passedProps, style })=> {
return (
<div onClick={toggleState} style={style}>
{ passedProps.text }
</div>
);
};
class MouseTracker extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick(event) {
const coords = {
x: event.clientX,
y: event.clientY
};
this.props.toggleState(coords);
}
render() {
return (
<div style={{ height: '100px' }} onClick={this.handleClick}>
<h1>Click me!</h1>
</div>
);
}
}
const MouseInformer = ({toggleState, passedProps}) => (
<div>
You clicked {passedProps.x}, {passedProps.y}!
<button onClick={toggleState}>Go Back</button>
</div>
);
class SlidePair extends Component {
constructor(props){
super(props);
this.state = { left: true, passedProps: {}};
this.toggleState = this.toggleState.bind(this);
}
toggleState(passedProps){
const left = !this.state.left;
console.log(`Toggling left to ${left}`);
this.setState({ left, passedProps });
}
render(){
const {left, passedProps } = this.state;
return(
<div style={{position: 'relative'}}>
<Slide left when={left} >
<div style={ {position: 'absolute', top: '0px', right: '0px', width: '100%', zIndex: left ? '998' : -1 }}>
{this.props.renderLeft(this.toggleState, passedProps)}
</div>
</Slide>
<Slide right when={!left}>
<div style={{position: 'absolute', top: '0px', right: '0px', width: '100%', zIndex: left ? -1 : 1}}>
{ this.props.renderRight(this.toggleState, passedProps) }
</div>
</Slide>
</div>
)
}
}
class App extends Component {
render(){
const redBox = (toggleState, passedProps)=>(
<RedBox toggleState={toggleState}
style={{width: '100%', border: '5px solid red', height: '100px'}}/>
);
const blueBox = (toggleState, passedProps) => (
<BlueBox
toggleState={toggleState}
passedProps={passedProps}
style={{width: '100%', border: '5px solid blue', height: '100px'}}
/>
);
const mouseTracker = (toggleState, passedProps) => (
<MouseTracker toggleState={toggleState} passedProps={passedProps} style={{top: '300px'}}/>
);
const mouseInformer = (toggleState, passedProps) => (
<MouseInformer toggleState={toggleState} passedProps={passedProps} style={{top: '300px'}}/>
);
return (
<div className="App">
<SlidePair renderLeft={redBox} renderRight={blueBox}/>
<br/>
<SlidePair renderLeft={mouseTracker} renderRight={mouseInformer} />
</div>
);
}
}
export default App;
Thanks in advance for any help.

Categories