I want to send element's index on click in function. Because I should change data for every element and get it from array.
How can I get key in MainBlock from List? Is it possible? Or I do something wrong?
I'm very new in React and do many mistakes.
var MainBlock = React.createClass({
Click: function() {
// I need to get element KEY
// var data = array[key]
},
render: function() {
return (
<List Click={this.props.Click.bind(null, this)}>
);
}
});
var List = React.createClass({
render: function() {
var ItemNodes = this.props.data.map(function(step, index) {
return (
<Item className="class" Click={this.props.Click.bind(null, this)} key={index} />
);
}.bind(this));
return (
<ul>
{ItemNodes}
</ul>
);
}
});
var StepWindow = React.createClass({
render: function() {
return (
<li onClick={this.props.Click}>
yo!
</li>
);
}
});
Thank you for your help.
Try this:
Click={this.props.Click.bind(this, index)}
Click: function(idx, e){
}
check out the boundClick in the docs example
http://facebook.github.io/react/tips/expose-component-functions.html
edit I've edited this to show that the parameters passed to the Click function are in the different order. It was e, idx and should be idx, e.
Related
I have a JS Fiddle with the below code.
I have a dynamic component setup, which does work. If I do var Component = Switch or set Component to some other React component, it works. But I want to be able to have it switch when I click on it.
So I set up an onClick event. Yet its not firing. I get no log statements or any change. Any ideas why?
var Other = React.createClass({
render: function () {
return <h2>Test this craziness</h2>;
}
});
var Switch = React.createClass({
render: function () {
return <h2>A different one to switch with</h2>;
}
});
var Hello = React.createClass({
getInitialState: function() {
return {on: true};
},
handleClick: function() {
console.log('handleclick');
this.setState({on: ! this.state.on});
},
render: function() {
console.log(this.state);
var Component = this.state.on ? this.props.component.name : Switch;
return <Component onClick={this.handleClick} />;
}
});
ReactDOM.render(
<Hello component={{name: Other}} />,
document.getElementById('container')
);
Easy! When onClick is put directly on a Component, like you have done, it is NOT set as the onClick function. It is instead placed in this.props.onClick. You still need to add the onClick to your actual DOM Elements. See the attached JSFiddle!
You need to add the onClick attribute to an actual HTML element, i.e.
var Other = React.createClass({
render: function () {
return <h2 onClick={this.props.onClick}>Test this craziness</h2>;
}
});
I am building a todo list, and one of the functionalities is to display a list of completed tasks when the "completed" text is clicked and hide the list when it is clicked again. However, I can't get the first step - saving the state of the list, whether shown or hidden - to work.
There are several of these "CompletedRow" components (for different categories of tasks), and while clicking the text does toggle the state successfully, it seems that all these "CompletedRow" components share the same state - they are not independent. Why is this the case when I have already assigned keys to these components, and how can I solve this issue?
var CompletedRow = React.createClass({
getInitialState: function () {
return {
show: false
};
},
handleChange: function() {
this.setState.show = !this.setState.show;
console.log(this.state.show);
},
render: function() {
return (<tr>
<td
className="completed" colSpan="3" onClick={this.handleChange}
> {this.props.count} tasks completed
</td>
</tr>);
}
});
var TaskTable = React.createClass({
// other code omitted for simplicity
render: function() {
var rows = [];
var completedTasks = 0;
this.state.taskList.forEach(function(task, index) {
// do something
if (completedTasks > 0) {
rows.push(<CompletedRow
count={completedTasks}
key={getKey()}
taskList={this.state.taskList}
/>);
completedTasks = 0;
}
}.bind(this));
return (
<div>
<table>
<tbody>{rows}</tbody>
</table>
</div>
);
}
});
This may be a typo, but you have a line in handleChange that is toggling a property attached to the setState function. This is shared by all the components
this.setState.show = !this.setState.show;
That line should be
this.setState({show: !this.state.show});
Also, the console.log on the following line will reflect the old state because setState is asynchronous to allow batching of state changes.
I know that the browser timers exist, but I've never used them and don't know which are the ones that I need to use.
I'm using React Native and I want a code block to execute only during a 10 second interval, the lower bound of the interval should be when the first click to the button is made. This is what I have:
<TouchableHighlight style={styles.button}
onPress={() => nClicks++}>
<Text style={styles.buttonText}>
Tap Here!
</Text>
</TouchableHighlight>
The action is responding perfectly, for every click the value of the global variable increases by 1. I just need to somehow find a way to add the time interval constraint. Any ideas?
within the onPress() function, you might probably want to put setInterval() method. You can try the following code:
var SetIntervalMixin = {
componentWillMount: function() {
this.intervals = [];
},
setInterval: function() {
this.intervals.map(clearInterval);
this.intervals.push(setInterval.apply(null, arguments));
}
};
var App = React.createClass({
mixins: [SetIntervalMixin], // Use the mixin
getInitialState: function() {
return {
seconds: 0,
nClicks: 0
};
},
onPress: function( plus ) {
//this.setState({nClicks: plus});
this.setInterval(this.codeToExcecute, plus * 1000); // Call a method on the mixin
this.setState({nClicks: this.state.nClicks + 1});
},
codeToExcecute: function() {
console.log('Im the code to excecute');
},
render: function() {
return (
<div>
<p>
React has been running for {this.state.seconds} seconds. nClick: { this.state.nClicks }
</p>
<button onClick={ this.onPress.bind(null, this.state.nClicks + 1) }>Click</button>
</div>
);
}
});
React.render(
<App />,
document.getElementById('example')
);
The demo: http://jsbin.com/biyibu/2/edit
Here is the piece of code from the react-grid-layout documentation
var ReactGridLayout = require('react-grid-layout');
//...
render: function() {
var layout = getOrGenerateLayout();
return (
<ReactGridLayout className="layout" layout={layout}
cols={12} rowHeight={30}>
<div key={1}>1</div>
</ReactGridLayout>
)
}
With this I want to extract the div element in an React component. So I've added this piece of code :
var SimpleDiv = React.createClass({
render() {
return (<div>1</div>);
}
});
And so the first part becomes :
var ReactGridLayout = require('react-grid-layout');
//...
render: function() {
var layout = getOrGenerateLayout();
return (
<ReactGridLayout className="layout" layout={layout}
cols={12} rowHeight={30}>
<SimpleDiv key={1}>1</SimpleDiv>
</ReactGridLayout>
)
}
And the problem is that it's not working, the div element is present but no class name transformation occurs.
Am I missing something ?
The problem is that you are wrapping the div element in your custom component so when the ReactGridLayout component tries to set properties on its children it'll be setting them on the SimpleDiv component. You might be able to make it work by passing along the props like:
var SimpleDiv = React.createClass({
render() {
return (<div {...this.props}>1</div>);
}
});
or explicitly:
var SimpleDiv = React.createClass({
render() {
return (<div style={this.props.style} className={this.props.className}>1</div>);
}
});
But I'm not too familiar with ReactGridLayout so if that doesn't work you may have to ping them and ask if it's possible.
If you don't mind an extra 'div' element, you could use:
render: function() {
var layout = getOrGenerateLayout();
return (
<ReactGridLayout className="layout" layout={layout}
cols={12} rowHeight={30}>
<div key={1}><SimpleDiv>1</SimpleDiv></div>
</ReactGridLayout>
)
}
I am attempting to implement a Pub/Sub pattern in jQuery with the following code :
$.each({
trigger : 'publish',
on : 'subscribe',
off : 'unsubscribe'
}, function ( key, val) {
jQuery[val] = function() {
o[key].apply( o, arguments );
};
});
This works fine until I attempt to build something with multiple instances.
I have an activity object that is applied to each $('.activity_radio') div element. When I click on a radio button inside any $('.activity_radio') div the $.subscribe event will trigger (X) amount of times based on the number of activity_radio divs on are on the page.
How do I publish/subscribe events based only within a particular div?
Code
Radio Activity ( radio-activity.js )
var activity = {
init : function ( element ) {
// get our boilerplate code
this.activity = new util.factories.activity();
this.element = element;
this.$element = $(element);
// other init code
// gather our radio elements
this.target_element = this.$elem.find('input[type=radio]');
// send our radio elements to onSelect
this.activity.onSelect(this.target_element);
// trigger click function that will subscribe us to onSelect publish events
this.click()
},
// subscribe to events
click : function()
{
$.subscribe('activity.input.select', function ( event, data ){
// we have access to the value the user has clicked
console.log(data);
// trigger another function // do something else
});
}
}
Base Activity Boilerplate Code ( activity-factory.js )
var activity_factory = factory.extend({
init: function(e)
{
// init code
},
onSelect : function ( inputs ) {
inputs.on('click', function(){
// do some processing
// retrieve the value
var data = $(this).val();
// announce that the event has occured;
$.publish( 'activity.input.select', data );
});
}
}
});
Triggered when DOM is ready
$(function(){
// foreach DOM element with the class of activity_radio
$('.activity_radio').each(function(){
// trigger the init func in activity object
activity.init(this);
});
});
You can write your subscribe/publish as a plugins
$.each({
trigger : 'publish',
on : 'subscribe',
off : 'unsubscribe'
}, function ( key, val) {
jQuery.fn[val] = function() {
this[key].apply(this, Array.prototype.slice.call(arguments));
};
});
And you will be able to call it on $element
this.$element.subscribe('activity.input.select', function(event, data) {
and
onSelect: function ( inputs ) {
var self = this;
inputs.on('click', function(){
// do some processing
// retrieve the value
var data = $(this).val();
// announce that the event has occured;
self.$element.publish('activity.input.select', data);
});
}