I want to make clock made of components in react. Each value I want to be from different components. I got that code:
import React from 'react';
import ReactDOM from 'react-dom';
class ClockTimeHour extends React.Component{
render(){
return <h1>{this.props.date.getHours()}</h1>
}
}
class ClockTimeMinute extends React.Component{
render(){
return <h1>{this.props.date.getMinutes()}</h1>
}
}
class ClockTimeSecond extends React.Component{
render(){
return <h1>{this.props.date.getSeconds()}</h1>
}
}
class ClockDateYear extends React.Component{
render(){
return <h1>{this.props.date.getFullYear()}</h1>
}
}
class ClockDateMonth extends React.Component{
render(){
return <h1>{this.props.date.getMonth()}</h1>
}
}
class ClockDateDay extends React.Component{
render(){
return <h1>{this.props.date.getDate()}</h1>
}
}
class ClockTime extends React.Component{
render(){
return (
<div>
<ClockTimeHour date={this.state.now}/>
<ClockTimeMinute date={this.state.now}/>
<ClockTimeSecond date={this.state.now}/>
</div>
);
}
}
class ClockDate extends React.Component{
render(){
return (
<div>
<ClockDateYear date={this.state.now}/>
<ClockDateMonth date={this.state.now}/>
<ClockDateDay date={this.state.now}/>
</div>
);
}
}
class Clock extends React.Component{
constructor(props){
super(props)
this.state={
now: new Date()
}
}
componentDidMount() {
this.timerId=setInterval(()=>{
this.setState({ now : new Date() });
},1000);
}
render(){
return (
<div>
<ClockTime date={this.state.now}/>
<ClockDate date={this.state.now}/>
</div>
);
}
}
document.addEventListener('DOMContentLoaded', function(){
ReactDOM.render(
<Clock/>,
document.getElementById('app')
);
});
and when I am running it I got: Uncaught TypeError: Cannot read property 'now' of null at ClockTime.render
You are not setting the state for the component you mentioned, but your are passing through it props as date here <ClockTime date={this.state.now}/>, so I assume you might want to change from:
class ClockTime extends React.Component{
render(){
return <div>
<ClockTimeHour date={this.state.now}/>
<ClockTimeMinute date={this.state.now}/>
<ClockTimeSecond date={this.state.now}/>
</div>
}
}
to:
class ClockTime extends React.Component{
render(){
return (
<div>
<ClockTimeHour date={this.props.date}/>
<ClockTimeMinute date={this.props.date}/>
<ClockTimeSecond date={this.props.date}/>
</div>
);
}
}
You can find here a working example, using your code but applying the changes I've seggested.
Related
I am trying to over ride some function of a prime react button component but i am getting this error while extending prime react button component class.
Here is my code:
import { Button } from "primereact/button";
class BtnBox extends Button {
constructor(props) {
super(props);
this.renderLabel = this.renderLabel.bind(this);
}
renderLabel() {
return <span>icon</span>;
}
}
class IconButton extends React.Component {
render() {
return (
<div className="icon-button">
<BtnBox {...this.props} />
</div>
);
}
}
export default IconButton;
can you try this form ?
import { Button } from "primereact/button";
class BtnBox extends Button {
constructor(props) {
super(props);
}
render = () => <span>{this.props.name}</span>;
}
class IconButton extends React.Component {
render() {
return (
<div className="icon-button">
<BtnBox name='add item' />
</div>
);
}
}
export default IconButton;
if doesn't suite for you, can you share more detail ?
How to access the state variable testState from the different class UserAuthentication?
I have tried this without success:
import React from 'react';
import UserAuthenticationUI from './UserAuthentication/UserAuthenticationUI';
class App extends React.Component {
constructor(props) {
super(props);
this.userAuthenticationUI = React.createRef();
this.state={
testState: 'test message'
}
}
render() {
return(
<div>
<UserAuthenticationUI ref={this.userAuthenticationUI} />
<div>
)
}
}
export default App;
How to access this.state.teststate from class UserAuthenticationUI?
import React from "react";
import App from '../App';
class UserAuthenticationUI extends React.Component {
constructor(props) {
super(props);
this.app = React.createRef();
}
render() {
return(
<div>
<App ref={this.app} />
{console.log(this.state.testState)}
</div>
)
}
}
export default UserAuthenticationUI;
You need to pass it via props.
import React from "react";
import UserAuthenticationUI from "./UserAuthentication/UserAuthenticationUI";
class App extends React.Component {
constructor(props) {
super(props);
this.userAuthenticationUI = React.createRef();
this.setParentState = this.setParentState.bind(this);
this.state = {
testState: "test message"
};
}
setParentState(newStateValue){ // this is called from the child component
this.setState({
testState: newStateValue
})
};
render() {
return (
<div>
<UserAuthenticationUI
stateVariable={this.state.testState}
ref={this.userAuthenticationUI}
setParentState={this.setParentState}
/>
</div>
);
}
}
export default App;
UserAuthenticationUI:
import React from "react";
import App from "../App";
class UserAuthenticationUI extends React.Component {
constructor(props) {
super(props);
this.app = React.createRef();
this.onClick = this.onClick.bind(this);
}
onClick(){
const newStateValue = 'new parent state value';
if(typeof this.props.setParentState !== 'undefined'){
this.props.setParentState(newStateValue);
}
}
render() {
const stateProps = this.props.stateVariable;
return (
<div>
<App ref={this.app} />
<div onClick={this.onClick} />
{console.log(stateProps)}
</div>
);
}
}
export default UserAuthenticationUI;
You should think differently.
Try to read the variable via GET methods and set via SET methods.
Do not try to call the variable immediately
Hope this helps.
you can pass it through Props:
import React from 'react';
import UserAuthenticationUI from
'./UserAuthentication/UserAuthenticationUI';
class App extends React.Component {
constructor(props) {
super(props);
this.userAuthenticationUI = React.createRef();
this.state={
testState: 'test message'
}
}
render(){
return(
<div>
<UserAuthenticationUI testState={this.state.testState} />
<div>
)}
}
export default App;
UserAuthenticationUI:
import React from "react";
import App from '../App';
class UserAuthenticationUI extends React.Component
{
constructor(props){
super(props);
}
render(){
return(
<div>
<App/>
{console.log(this.props.testState)}
</div>
)}
}
export default UserAuthenticationUI;
You can access it via props:
<div>
<UserAuthenticationUI testState={this.state.testState} ref={this.userAuthenticationUI} />
<div>
and in UserAuthenticationUI class access it:
<div>
<App ref={this.app} />
{console.log(this.props.testState)}
</div>
I have a simple component like this
import { Component } from 'react'
export default class SearchList extends Component(){
constructor(props){
super(props);
}
render(){
const { placeholder } = this.props;
return(
<div className="searchList">
<input type="text" placeholder={placeholder}/>
<button>Search</button>
</div>
)
}
}
The somewhere I do <SearchList placeholder="Search Area" />
Why I got error of cannot set property of props of undefined?
When you write a react component extending React.Component you don't need the extra () after React.Component
Use this
export default class SearchList extends Component{
constructor(props){
super(props);
}
render(){
const { placeholder } = this.props;
return(
<div className="searchList">
<input type="text" placeholder={placeholder}/>
<button>Search</button>
</div>
)
}
}
I would like to create Dropdown component.
When I click on the DropdownHandler component, I would like to save the state isOpen which can be true or false. If true, this same state is used by <DropdownContent/> to show the content. And by default, the state isOpen is false in <Dropdown /> component
How can I do that please?
App.jsx
import React from 'react';
import {Dropdown, DropdownHandler, DropdownContent} from '../../components/Dropdown/Dropdown.jsx';
class HeaderConnected extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<Dropdown>
<DropdownHandler>
<Avatar title="Roberto"></Avatar>
</DropdownHandler>
<DropdownContent>
<li>Menu</li>
<li>Settings</li>
</DropdownContent>
</Dropdown>
</div>
);
}
}
export default HeaderConnected;
Dropdown.jsx
export class Dropdown extends React.Component {
constructor(props) {
super(props);
this.state = {
opened: false
}
}
render() {
return (
<div className="DROPDOWN">
{this.props.children}
</div>
);
}
}
export class DropdownHandler extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div className="DROPDOWN__HANDLER">
{this.props.children}
</div>
);
}
}
export class DropdownContent extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div className="DROPDOWN__CONTENT">
{this.props.children}
</div>
);
}
}
If you don't want use redux.
You set and control your opend like state of child component and set it to DropdownContent with props. So when you will change opend by click on DropdownHandler, your DropdownContent will recive new propse and call re-render.
import React from 'react';
import {Dropdown, DropdownHandler, DropdownContent} from '../../components/Dropdown/Dropdown.jsx';
class HeaderConnected extends React.Component {
constructor(props) {
super(props);
this.state = {
opened: false
}
}
onClick(){
let condition = this.state.opened;
this.setState({opened: !condition });
}
render() {
return (
<div>
<Dropdown>
<DropdownHandler onClick={this.onClick.bind(this)}>
<Avatar title="Roberto"></Avatar>
</DropdownHandler>
<DropdownContent opened={this.state.opened}>
<li>Menu</li>
<li>Settings</li>
</DropdownContent>
</Dropdown>
</div>
);
}
}
export default HeaderConnected;
I found a solution based on #Andrew answers. Not sure if this is right. But it solves the shared state, only use by Dropdown. I pass the handler and content via props
What do you think?
App.jsx
import React from 'react';
import {Dropdown} from '../../components/Dropdown/Dropdown.jsx';
class HeaderConnected extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<Dropdown handler={<Avatar title="Roberto" />}>
<li>Menu</li>
<li>Settings</li>
</Dropdown>
</div>
);
}
}
export default HeaderConnected;
Dropdown.jsx
export class Dropdown extends React.Component {
constructor(props) {
super(props);
this.state = {
opened: false
}
}
render() {
return (
<div className="DROPDOWN">
<div className="DROPDOWN_HANDLER" onClick="...">
{this.props.handler}
</div>
<div className="DROPDOWN_CONTENT">
{this.props.children}
</div>
</div>
);
}
}
Feel free to change the name of the callback "onOpen"
export class Dropdown extends React.Component {
state = {
open: false
}
handleOpen = () => {
this.setState({open: !this.state.open});
}
render() {
return (
<div className="DROPDOWN">
{React.cloneElement(this.props.children, { open: this.state.open, onOpen: this.handleOpen })}
</div>
);
}
}
export class DropdownHandler extends React.Component {
static propTypes = {
open: React.PropTypes.bool.isRequired,
onOpen: React.PropTypes.func.isRequired
}
render() {
return (
<div className="DROPDOWN__HANDLER" onClick={this.props.onOpen}>
{this.props.children}
</div>
);
}
}
export class DropdownContent extends React.Component {
static propTypes = {
open: React.PropTypes.bool.isRequired,
onOpen: React.PropTypes.func.isRequired
}
render() {
// handle visibility here
return (
<div className="DROPDOWN__CONTENT">
{this.props.children}
</div>
);
}
}
i have the following react component Timepicker:
export default class TimePicker extends Component{
render(){
return(
<div>
<input id={this.props.nameID} type="text"></input>
</div>);
}
}
TimePicker is used by SingleTask:
export default class SingleTask extends Component{
....
render(){
....
<TimePicker nameID="time" />
.....
}
}
How can I access the input value in TimePicker from SingleTask?
You can solve this in 2 ways:
only change in SingleTask component:
Add a ref to TimePicker component and access it's DOM. From there you can query your input by your choice of jQuery selector. Here I have used tag selector (Note: There is no dependency of the jQuery to be included).
:
export default class SingleTask extends Component{
yourFunction(){
var selectedTime = React.findDOMNode(this.refs.timePickerComp).querySelector('input').value;
}
render(){
....
<TimePicker ref="timePickerComp" nameID="time" />
.....
}
}
Expose data through function of child component (The React way):
TimePicker :
export default class TimePicker extends Component{
function getSelectedTime(){
return document.getElementById(this.props.nameID).value;
}
render(){
return(
<div>
<input id={this.props.nameID} type="text"></input>
</div>);
}
}
SingleTask :
export default class SingleTask extends Component{
yourFunctionWhereYouNeedTime(){
var timeSelected = this.refs.timePickerComp.getSelectedTime(); // here you'll access the child component data.
}
render(){
....
<TimePicker ref="timePickerComp" nameID="time" />
.....
}
}