Rendering multiple buttons with onClick function in React - javascript

I am trying to render multiple buttons in react using map but i am getting an errors.
var NameArray = [{"name":"number0"},{"name":"number1"},{"name":"number2"}];
class RenderButtons extends React.Component {
constructor() {
super();
this.onClick = this.handleClick.bind(this);
}
handleClick(event) {
const {id} = event.target;
console.log(id);
}
render() {
return (
<div>
{NameArray.map((obj, index) =>
<h3 id={index} onClick={this.onClick}>
{obj.name}
</h3>
)}
</div>
);
}
}
ReactDOM.render(
<RenderButtons />,
document.querySelector('app'));
<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="app"></div>
I am using index as Id for my buttons and NameArray properties as name of the buttons.
I tried spliting render of buttons to new function but i am not sure how to do this.

Apparently you miss # sign in your querySelector function.
document.querySelector('#app');

Related

Render a component from another class using function

So, I have a class like this:
class Blah extends Component {
constructor(props) {
super(props);
}
handleComponent = (event) => {
let divid = event.target.getAttribute('id');
if (divid === 'col') {
// I want to render component by this condition
} else if (divid === 'ro') {
// or I want to render component by this condition
} else {
//or I want to render component by this condition
}
};
render() {
const { classes } = this.props;
return (
<div>
<div id = 'col' onClick={this.handleComponent}>Sheep</div>
<div id = 'ro' onClick={this.handleComponent}>Cow</div>
<div id = 'ball' onClick={this.handleComponent}>Dog</div>
{ I want to render my component here after click }
</div>
);
}
}
I have another class written on top of this:
class Flow extends Component {
constructor(props){
super(props);
};
render() {
return(
<div style={{background:'somecolor'...blah blah}}>Clap</div>
);
}
}
And I am Passing this by:
var foo = withStyles(styles)(Flow)
I have tried returning components but I am not getting anywhere.
I can use ternary operator but it still will render only one of two but I have three component have three design for each of them.
I want to render one of them to render on some condition as stated above.
If I use states that for toggle that will too have two components for render. Don't go on the code, this is made up, So any Ideas ? Fragments ? Any help will be appreciated. Thank you.
To render component by condition simply use switch statement.
In my example we use state to store current active component.
renderMyComponent method takes care of rendering one of three possible components.
handleChange method changes current state and triggers new render of App component.
This example use class properties plugin.
renderMyComponent = () => {
means autobind and is the same as using in constuctor method
this.renderMyComponent = this.renderMyComponent.bind(this);
Working example:
const ComponentOne = () => <div>Hi, i am component one</div>;
const ComponentTwo = () => <div>Hi, i am component two</div>;
const ComponentThree = () => <div>Hi, i am component three</div>;
class App extends React.Component {
state = { current: 0 }
renderMyComponent = () => {
// Our switch conditional render
switch(this.state.current) {
case 0:
return <ComponentOne />;
case 1:
return <ComponentTwo />;
case 2:
return <ComponentThree />;
default:
return null;
}
}
handleChange = (event) => {
// We are looking for data-trigger attribute
// In this example we expect type number but trigger holds string
// That's why we 'cast' to a number using Number()
const current = Number(event.target.dataset.trigger);
// Sets new state of current component and triggers new render
this.setState({ current })
}
render() {
return (
<div>
<div>
Pick component to render
<button
type="button"
data-trigger="0"
onClick={this.handleChange}
>
Render 1
</button>
<button
type="button"
data-trigger="1"
onClick={this.handleChange}
>
Render 2
</button>
<button
type="button"
data-trigger="2"
onClick={this.handleChange}
>
Render 3
</button>
</div>
{this.renderMyComponent()}
</div>
)
}
}
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>
Reviewing your code:
You don't need constructor here.
...
constructor(props){
super(props);
}
...

Access to a several elements through one ref React

I wanna get access to multiple elements with using refs feature. Then after I could iterate through elements of this.tabs. Code below doesn't work, how fix it to make work? Solution, which I use now is document.querySelectorAll('tabs'), but it doesn't seems right for React.
class Comp extends React.Component {
constructor(props) {
super(props);
this.tabs = React.createRef();
}
componentDidMount() {
console.log(this.tabs);
}
render() {
return (
<div>
<span class="tab" ref={this.tabs}>One</span>
<span class="tab" ref={this.tabs}>Two</span>
<span class="tab" ref={this.tabs}>Three</span>
</div>
);
}
}
ReactDOM.render(
<Comp />,
document.getElementById('app')
);
<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="app"></div>
You're assigning refs incorrect way. Do it in the early beginning of render() method:
this.tabs = []
refs are going to be assigned via
<span className="tab" ref={(tab) => { this.tabs.push(tab) }}>One</span>
I hope you could call this.tabs this case!

switch components in react js

I'm doing a singlepage application and would like to switch a component.
Here is an image how it looks like:
If I click on the button in component 3, I will switch the component 3 with 5.
So maybe like component 3 is a view of all projects and if I click on one project, I will see a detail view of the project with some information.
I created two different components for this.
All other components should stay at the same place.
Here is my code how I switch the components:
this.state.detailVisible
? <ProjectDetailView/>
: null
I'm not sure if is the correct react way to do it. Also I have two different css files for component 3 and 5. If I'm switching the two component, I have some class name irritations with my css.
If it's a better way to do it with routers?
How is the react way to do it?
thanks for your help :)
It all depends on your needs, if you need to render both component3 and component5 then a route won't be much of a help.
If you need to render only one of them then a route can be handy.
as for the syntax i prefer this:
this.state.detailVisible && <ProjectDetailView/>
here is a simple example:
const components = ["Component1", "Component2", "Component3"];
class Component extends React.Component {
constructor(props) {
super(props);
this.state = {
showDetails: false
};
this.onComponentClicked = this.onComponentClicked.bind(this);
}
onComponentClicked(e) {
this.setState({
showDetails: !this.state.showDetails
});
}
render() {
const { name } = this.props;
const { showDetails } = this.state;
return (
<div>
<div>Component{name}</div>
<button onClick={this.onComponentClicked}>Toggle Details</button>
{showDetails && <ComponentDetails name={name} />}
</div>
);
}
}
const ComponentDetails = ({ name }) => (
<div>
<div>Details of component{name}</div>
</div>
);
class App extends React.Component {
render() {
return (
<div>
<h2>Parent</h2>
{components.map(c => {
return (
<div>
<Component name={c} />
<hr />
</div>
);
})}
</div>
);
}
}
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>

React - Instance creation and usage of a class

I'm trying to get an instance of the class ActionEditor So that I'd be able to use its methods later:
function render() {
const toRender = responseActions.map((actionInstance) => {
currentActionEditing=actionInstance;
return <li>{ actionInstance === expandedAction ? <ActionEditor id={actionInstance.title} action={getActionByKey(actionInstance.actionType)} instance={actionInstance} state={actionInstance} /> : <button onClick={createOnClick(actionInstance)}>{actionInstance.title}</button>}</li>;
});
ReactDOM.render(
<div>
<div>{toRender}</div>
<button style={styleButtonGenerate} onClick={onGenerateClick}>Generate</button>
</div>,
document.getElementById('root')
);
}
I've attempted to use it through an onClick method like so:
function onGenerateClick() {
var editor = document.getElementById(currentActionEditing.title);
editor.prototype = ActionEditor;
editor.methodIWantToUse();
}
But it always turns out to be null/undefined.
I understand that it's not the best example but it should be enough to demonstrate the issue.
Is there a way around this?
I think what you want here is to save a ref to the component so it can be accessed, see in the example below how the sayHi method is called from the parent component.
class MyComponent extends React.Component {
sayHi() {
console.log('hi');
}
render() {
return (<div>I'm a component!</div>)
}
}
class App extends React.Component {
render() {
// just a way to show how to access a child component method.
setTimeout(() => {
this.node.sayHi();
}, 1000)
return (<MyComponent ref={(node) => this.node = node}/>)
}
}
ReactDOM.render(<App />, document.querySelector("body"))
<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>

react fire multiple function in an event

fireOne(){
}
render(){
return(
<p onClick={this.fireOne.bind(this)}></p>
)
}
Can I bind one event with 2 function? one function is for current component, I want to pass something down to the children component as well.
I think this is what you are trying to acomplish, but I'm not completely sure:
class MyComponent extends React.Component {
foo1 = () => { console.log('ahh');}
foo2 = () => { console.log('beh');}
render() {
return(<div onClick={() => {
this.foo1();
this.foo2();
}}>AHH </div>)
}
}
ReactDOM.render(<MyComponent />, 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"/>

Categories

Resources