class UserForm extends React.Component {
constructor(props) {
super(props);
const { user } = props;
}
_cancelForm() {
this.props.onCancel();
}
render() {
return (
<button onClick={this._cancelForm.bind(this)}> Cancel </button>
);
}
}
class UserCreate extends React.Component {
_navigateToLogin() {
console.log("hi")
}
render() {
return (
<div>
<UserForm onCancel={this._navigateToLogin.bind(this)}/>
</div>
);
}
}
ReactDOM.render(
<UserCreate/>,
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>
import React from 'react'
import { withRouter } from 'react-router-dom';
import UserForm from './UserForm'
import UsersService from '../services/UsersService'
class UserCreate extends React.Component{
_navigateToLogin() {
this.props.history.push('/homepage');
}
async _saveUser(user) {
await UsersService.createUser(user);
this._navigateToLogin();
}
render() {
return(
<div>
<UserForm
onCancel={this._navigateToLogin.bind(this)}
onSubmit={this._saveUser.bind(this)}
/>
</div>
);
}
}
export default withRouter(UserCreate)
import React from 'react'
import {
Button
} from '#material-ui/core'
export default class UserForm extends React.Component {
constructor(props) {
super(props);
const { user } = props;
this.state = {
...
}
_handleFormSubmit() {
const user = {
...
};
this.props.onSubmit(user);
}
_cancelForm() {
this.props.onCancel();
}
render () {
return (
<div style={{ width: '100%', height: 'auto', position: 'fixed', minWidth: '100%', minHeight: '100%', backgroundColor: '#50617C' }}>
<Button size="small" onClick={ this._cancelForm.bind(this) }>Back</Button>
<Button size="small" onClick={ this._handleFormSubmit.bind(this) }>Create</Button>
</div>
)
}
}
The error is present when I click the "Back" button on CreateAccountForm, it returns an error that says that the onCancel function is not a function. I'm sending it on the UserCreate by binding and I'm calling it on the function _cancelForm(). I was thinking that the error is that I'm missing something in the constructor according to some react documentation, I used before this method and it worked, right now I don't know what's happening.
The code you posted does not demonstrate the error, below is your code and it works just fine.
class UserForm extends React.Component {
constructor(props) {
super(props);
}
_cancelForm() {
this.props.onCancel();
}
render() {
return (
<button onClick={this._cancelForm.bind(this)}>
cancel
</button>
);
}
}
class UserCreate extends React.Component {
_navigateToLogin() {
console.log('in navigate login');
}
render() {
return (
<div>
<UserForm
onCancel={this._navigateToLogin.bind(this)}
/>
</div>
);
}
}
ReactDOM.render(
<UserCreate />,
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>
Can you provide a minimal snippet that reproduces the error you are getting?
You also don't need to bind the handler if you use arrow functions. For example:
_navigateToLogin = () => {//arrow function is automatically bound to this
console.log('in navigate login');
};
and
<UserForm onCancel={this._navigateToLogin} />
Related
I'm trying to do this example of react popout but it doesn't seem to be working.
https://github.com/JakeGinnivan/react-popout#readme
example is at the bottom.
import React from "react"
import Popout from "react-popout"
class PopupLogin extends React.Component {
constructor(props) {
super(props);
this.popout = this.popout.bind(this);
this.popoutClosed = this.popoutClosed.bind(this);
this.state = { isPoppedOut: false };
}
popout() {
this.setState({isPoppedOut: true});
}
popoutClosed() {
this.setState({isPoppedOut: false});
}
render() {
if (this.state.isPoppedOut) {
return (
<Popout title='Window title' onClosing={this.popoutClosed}>
<div>Popped out content!</div>
</Popout>
);
} else {
var popout = <span onClick={this.popout} className="buttonGlyphicon glyphicon glyphicon-export"></span>
return (
<div>
<strong>Section {popout}</strong>
<div>Inline content</div>
</div>
);
}
}
}
export default PopupLogin
This is supposed to look like http://jake.ginnivan.net/react-popout/ this.
But in my output looks like this.
You forgot to add a text to the span ,according to their docs, so as a result there was no link, hence no onClick was fired. You could style the link as per your needs
Sandbox: https://codesandbox.io/s/react-example-vxtu9
import React from "react";
import Popout from "react-popout";
import ReactDOM from "react-dom";
class PopupLogin extends React.Component {
constructor(props) {
super(props);
this.popout = this.popout.bind(this);
this.popoutClosed = this.popoutClosed.bind(this);
this.state = { isPoppedOut: false };
}
popout() {
this.setState({ isPoppedOut: true });
}
popoutClosed() {
this.setState({ isPoppedOut: false });
}
render() {
if (this.state.isPoppedOut) {
return (
<Popout
url="popout.html"
title="Window title"
onClosing={this.popoutClosed}
>
<div>Popped out content!</div>
</Popout>
);
} else {
var popout = (
<span
onClick={this.popout}
className="buttonGlyphicon glyphicon glyphicon-export"
>
Open
</span>
);
return (
<div>
<strong>Section {popout}</strong>
<div>Inline content</div>
</div>
);
}
}
}
ReactDOM.render(<PopupLogin />, document.getElementById("root"));
It looks like the code in documentation missing the text. Add (pop window out) in the popout.
import React from "react";
import Popout from "react-popout";
class PopupLogin extends React.Component {
constructor(props) {
super(props);
this.popout = this.popout.bind(this);
this.popoutClosed = this.popoutClosed.bind(this);
this.state = { isPoppedOut: false };
}
popout() {
this.setState({ isPoppedOut: true });
}
popoutClosed() {
this.setState({ isPoppedOut: false });
}
render() {
if (this.state.isPoppedOut) {
return (
<Popout title="Window title" onClosing={this.popoutClosed}>
<div>Popped out content!</div>
</Popout>
);
} else {
var popout = (
<span
onClick={this.popout}
className="buttonGlyphicon glyphicon glyphicon-export"
>
<a
style={{
textDecoration: "underline",
color: "blue",
cursor: "pointer"
}}
onClick={this.popout}
>
(pop window out)
</a>
</span>
);
return (
<div>
<strong>Section {popout}</strong>
<div>Inline content</div>
</div>
);
}
}
}
export default PopupLogin;
I am trying to use Auth0EditProfileWidget
getting error at line 65:
this.form = React.render( <FormControl data={data} onSubmit={onSubmit} />, container );
TypeError: react__WEBPACK_IMPORTED_MODULE_0___default.a.render is not
a function
can anybody help me?
Edited: code
import React from 'react';
import formSerialize from 'form-serialize';
import FieldTypeMapper from './FieldTypes/FieldTypeMapper'
class FormFieldList extends React.Component {
render() {
var fieldNodes = this.props.data.map( data => FieldTypeMapper(data.type)(data) );
return ( <div>{fieldNodes}</div> );
}
}
class ErrorItem extends React.Component {
render() {
return ( <li>{this.props.message}</li> );
}
}
class ErrorControl extends React.Component {
render() {
var errors = this.props.data.map( error => ( <ErrorItem key={error} message={error} /> ) );
var style = {};
if (errors.length === 0) {
style.display = 'none';
}
return ( <ul className="error" style={style}>{errors}</ul> );
}
}
class FormControl extends React.Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
this.state = props.data;
}
render() {
return (
<form onSubmit={this.handleSubmit} ref="editProfileForm">
<ErrorControl data={this.state.errors} />
<FormFieldList data={this.state.fields} />
<input type="submit" value="Save" />
</form>
);
}
handleSubmit(e) {
e.preventDefault();
var form = this.refs.editProfileForm.getDOMNode();
var data = formSerialize(form, {hash: true});
this.props.onSubmit(data);
}
}
export default class EditProfileForm {
constructor(container, data, onSubmit) {
this.form = React.render( <FormControl data={data} onSubmit={onSubmit} />, container );
}
render(data) {
this.form.setState(data);
}
}
Can you try changing your EditProfileForm class to this:
export default class EditProfileForm {
constructor(props) {
super(props)
}
render() {
return(<FormControl data={this.props.data} onSubmit={this.props.onSubmit} />)
}
}
And then call ReactDom.render() like this:
ReactDOM.render(<EditProfileForm data={dataProp} onSubmit={onSubmitProp} />, container);
export default class EditProfileForm {
constructor(container, data, onSubmit) {
this.form = React.render( <FormControl data={data} onSubmit={onSubmit} />, container );
}
render(data) {
this.form.setState(data);
}
}
things to note here, first, is EditProfileForm a react component or not because EditProfileForm do not extends React.Component
and Second thing is that this.form.setState(data); what is the value of setState why you use this.form.setState() what is it doing.
I have one question, how to use multiple toggle class
Please check my example below
I want to click <TaxItem /> and add some class to that element, and the second click to remove that class
import React, { Component } from "react";
import TaxItem from "./TaxItems/"
import Pentagon from "../../../assets/images/pentagon.png"
class Taxs extends Component {
constructor(props) {
super(props)
this.state = {
taxStatus: false
}
this.handleTaxStatus = this.handleTaxStatus.bind(this);
}
handleTaxStatus(element) {
console.log('sdasa', element)
}
render() {
return (
<div className="taxs">
<TaxItem
image={Pentagon}
name='Item 1'
taxStatus={false}
handleTaxStatus={this.handleTaxStatus(this)}
/>
<TaxItem
image={Pentagon}
name='Item 2'
taxStatus={false}
handleTaxStatus={this.handleTaxStatus(this)}
/>
</div>
)
}
}
export default Taxs
And here you can check button where I have onClick:
import React, { Component } from "react";
class TaxItem extends Component {
render() {
return (
<div className="tax-item" onClick={this.props.handleTaxStatus}>
<div className={this.props.taxStatus ? 'checked on' : 'checked'}><i className="icon icon-check"></i></div>
<img src={this.props.image} alt="Pentagon" />
<p>{this.props.name}</p>
</div>
)
}
}
export default TaxItem
How I can use THIS, something like jQuery.
As I said in the comment, I would suggest you to not use "THIS", which would mean use the refs, because it would lead to edit the DOM directly, which in React should be avoided when you can.
Instead, you could use an array of taxStatus property, one for each TaxItem, and using them as toggle, something like in the following:
class TaxItem extends React.Component {
localHandleClick = (_) => {
this.props.handleClick(this.props.taxStatusIndex);
};
render() {
const {taxStatus, handleClick} = this.props;
return (
<div
className={"button" + (taxStatus ? " checked" : " not-checked")}
onClick={this.localHandleClick} />
);
}
}
class Taxs extends React.Component {
constructor(props) {
super(props);
const taxItemCounter = props.num;
this.state = {
taxesStatus: new Array(taxItemCounter).fill(false)
}
}
handleClick = (i) => {
const taxesStatus = this.state.taxesStatus;
taxesStatus[i] = !taxesStatus[i];
this.setState({taxesStatus});
}
render() {
return (
<div>
{
this.state.taxesStatus.map((status, index) =>
<TaxItem
key={index}
taxStatusIndex={index}
handleClick={this.handleClick}
taxStatus={status} />
)}
</div>
);
}
}
ReactDOM.render(<Taxs num={3} />, document.getElementById('root'));
#import url(https://fonts.googleapis.com/css?family=Montserrat);
body {
font-family: 'Montserrat', sans-serif;
}
.button {
width: 100px;
height: 25px;
background: red;
margin: 10px;
cursor: pointer;
}
.button.checked {
background: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id='root'></div>
Anyways, if you DO want to use "THIS" (which again, would mean using the refs), I can provide you an example.
I am wondering how to change a display few elements from hide to visible in React. I have 4 section and for each section button. Start section has start button, About section has about button, Skills section has skills button and Contact section has contact button. How to make it when im clicking Start all others sections get instantly display: none and only Skills section is visible? By clicking About button, others get hide (none) and only About is visible? Etc to others sections.
I know that i have to make a handleonclick but idk how.
Should it work with state?
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
class Start extends Component {
render() {
return (
<div className='start'>
</div>
);
}
}
class About extends Component {
render() {
return (
<div className='about'>
</div>
);
}
}
class Skills extends Component {
render() {
return (
<div className='skills'>
</div>
);
}
}
class Contact extends Component {
render() {
return (
<div className='contact'>
</div>
);
}
}
class Buttons extends Component {
render() {
return (
<div className="buttons">
<button>Start</button>
<button>About</button>
<button>Skills</button>
<button>Contact</button>
</div>
);
}
}
class App extends Component {
render() {
return (
<div className="App">
<Buttons />
<Main />
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
registerServiceWorker();
<div id="root"></div>
<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>
Keep a state activeSection in the parent container called App. Then, pass it as a props to the child section components, About, Skills etc. Also add a method handleToggleSection, which you can call on click to the buttons and change the state activeSection to that corresponding section name. Inside all section components, About, Skills etc., check the current section name. If the name matches, then return the html or return null. Remember, when you return null, that component don't mount. If you want to keep the components mount regardless they are visible or not, then u need to use css classes like show, hide etc.
Here is the demo.
// import React from "react";
// import ReactDOM from "react-dom";
class Start extends React.Component {
get show() {
return this.props.activeSection === "start";
}
render() {
if (this.show) {
return <div className="start"> Start </div>;
} else {
return null;
}
}
}
class About extends React.Component {
get show() {
return this.props.activeSection === "about";
}
render() {
if (this.show) {
return <div className="about"> About </div>;
} else {
return null;
}
}
}
class Skills extends React.Component {
get show() {
return this.props.activeSection === "skills";
}
render() {
if (this.show) {
return <div className="skills"> Skills </div>;
} else {
return null;
}
}
}
class Contact extends React.Component {
get show() {
return this.props.activeSection === "contact";
}
render() {
if (this.show) {
return <div className="contact"> Contact </div>;
} else {
return null;
}
}
}
const Buttons = ({ onToggle }) => (
<div className="buttons">
<button name="start" onClick={onToggle}>
Start
</button>
<button name="about" onClick={onToggle}>
About
</button>
<button name="skills" onClick={onToggle}>
Skills
</button>
<button name="contact" onClick={onToggle}>
Contact
</button>
</div>
);
const Main = ({ activeSection }) => (
<React.Fragment>
<Start activeSection={activeSection} />
<About activeSection={activeSection} />
<Skills activeSection={activeSection} />
<Contact activeSection={activeSection} />
</React.Fragment>
);
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
activeSection: ""
};
this.handleToggleSection = this.handleToggleSection.bind(this);
}
handleToggleSection(e) {
const { name } = e.target;
this.setState(() => ({
activeSection: name
}));
}
render() {
return (
<div className="App">
<Buttons onToggle={this.handleToggleSection} />
<Main activeSection={this.state.activeSection} />
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
.App {
font-family: sans-serif;
text-align: center;
}
.show {
display: block;
}
.hide {
display: none;
}
<script crossorigin src="https://unpkg.com/react#16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#16/umd/react-dom.production.min.js"></script>
<div id="root"></div>
You can use conditional rendering.
selectSection = section => {
this.setState({ section })
}
render() {
return (
<div className="App">
<Buttons onClick={this.selectSection} />
{this.state.section === "start" && <Start>}
{this.state.section === "about" && <About>}
</div>
);
}
Also, instead of the if you can use switch.
We have been experiencing some problems in using react now but it kinda boils to one part of how we have been using react.
How should we have been showing/hiding child components?
This is how we have coded it (this are only snippets of our components)...
_click: function() {
if ($('#add-here').is(':empty'))
React.render(<Child />, $('#add-here')[0]);
else
React.unmountComponentAtNode($('#add-here')[0]);
},
render: function() {
return(
<div>
<div onClick={this._click}>Parent - click me to add child</div>
<div id="add-here"></div>
</div>
)
}
and lately I've been reading examples like it should've been somewhere along this lines:
getInitialState: function () {
return { showChild: false };
},
_click: function() {
this.setState({showChild: !this.state.showChild});
},
render: function() {
return(
<div>
<div onClick={this._click}>Parent - click me to add child</div>
{this.state.showChild ? <Child /> : null}
</div>
)
}
Should I have been using that React.render()? It seems to stop various things like shouldComponentUpdate to cascade to child and things like e.stopPropagation...
I've provided a working example that follows your second approach. Updating the component's state is the preferred way to show/hide children.
Given you have this container:
<div id="container">
</div>
you can either use modern Javascript (ES6, first example) or classic JavaScript (ES5, second example) to implement the component logic:
Show/hide components using ES6
Try this demo live on JSFiddle
class Child extends React.Component {
render() {
return (<div>I'm the child</div>);
}
}
class ShowHide extends React.Component {
constructor() {
super();
this.state = {
childVisible: false
}
}
render() {
return (
<div>
<div onClick={() => this.onClick()}>
Parent - click me to show/hide my child
</div>
{
this.state.childVisible
? <Child />
: null
}
</div>
)
}
onClick() {
this.setState(prevState => ({ childVisible: !prevState.childVisible }));
}
};
React.render(<ShowHide />, document.getElementById('container'));
Show/hide components using ES5
Try this demo live on JSFiddle
var Child = React.createClass({
render: function() {
return (<div>I'm the child</div>);
}
});
var ShowHide = React.createClass({
getInitialState: function () {
return { childVisible: false };
},
render: function() {
return (
<div>
<div onClick={this.onClick}>
Parent - click me to show/hide my child
</div>
{
this.state.childVisible
? <Child />
: null
}
</div>
)
},
onClick: function() {
this.setState({childVisible: !this.state.childVisible});
}
});
React.render(<ShowHide />, document.body);
/* eslint-disable jsx-a11y/img-has-alt,class-methods-use-this */
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import todoStyle from 'src/style/todo-style.scss';
import { Router, Route, hashHistory as history } from 'react-router';
import Myaccount from 'src/components/myaccount.jsx';
export default class Headermenu extends Component {
constructor(){
super();
// Initial state
this.state = { open: false };
}
toggle() {
this.setState({
open: !this.state.open
});
}
componentdidMount() {
this.menuclickevent = this.menuclickevent.bind(this);
this.collapse = this.collapse.bind(this);
this.myaccount = this.myaccount.bind(this);
this.logout = this.logout.bind(this);
}
render() {
return (
<div>
<div style={{ textAlign: 'center', marginTop: '10px' }} id="menudiv" onBlur={this.collapse}>
<button onClick={this.toggle.bind(this)} > Menu </button>
<div id="demo" className={"collapse" + (this.state.open ? ' in' : '')}>
<label className="menu_items" onClick={this.myaccount}>MyAccount</label>
<div onClick={this.logout}>
Logout
</div>
</div>
</div>
</div>
);
}
menuclickevent() {
const listmenu = document.getElementById('listmenu');
listmenu.style.display = 'block';
}
logout() {
console.log('Logout');
}
myaccount() {
history.push('/myaccount');
window.location.reload();
}
}