I am working off of course example "Todo" app by trying to incorporate Foundation Modal. I have three components in question: TodoList.jsx, Todo.jsx, and TodoModal.jsx.
What I want is a link to show up below each todo in todoList to popup a modal with todo contents. My problem: I can launch the Modal, but same Modal pops up regardless of which todo link I'm clicking. It seems like I am not able to update the props in TodoModal.jsx and may be component lifecycle in React, but I really need help proceeding ahead. I just took an online React course, so I am still new. Any help is greatly appreciated!
Below are TodoList.jsx (which sends todo data to TodoModal.jsx and Todo.jsx) and TodoModal.jsx.
TodoList.jsx
var React = require('react');
var {connect} = require('react-redux');
import Todo from 'Todo';
var TodoAPI = require('TodoAPI');
import TodoModal from 'TodoModal';
export var TodoList = React.createClass({
render: function () {
var {todos, showCompleted, searchText} = this.props;
var renderTodos = () => {
var filteredTodos = TodoAPI.filterTodos(todos, showCompleted, searchText);
if (filteredTodos.length === 0) {
return ( <p className="container__message">Nothing To Do</p> );
}
return filteredTodos.map((todo) => {
return (
<div>
<Todo key={todo.id} {...todo}/>
<div>
<a data-open="item-modal">
{todo.id}
</a>
<TodoModal todo={todo}/>
</div>
</div>
);
});
};
return (
<div>
{renderTodos()}
</div>
)
}
});
export default connect((state) => {return state })(TodoList);
TodoModal.jsx:
var React = require('react');
var ReactDOM = require('react-dom');
var ReactDOMServer = require('react-dom/server');
var TodoModal = React.createClass({
componentDidMount: function () {
var modalMarkup = (
<div id="item-modal" className="reveal tiny text-center" data-reveal="">
<h4>{this.props.todo.text}</h4>
<p>{this.props.todo.id}</p>
<p>
<button className="button hollow" data-close="">
Okay
</button>
</p>
</div>
);
var $modal = $(ReactDOMServer.renderToString(modalMarkup));
$(ReactDOM.findDOMNode(this)).html($modal);
var modal = new Foundation.Reveal($("#item-modal"));
},
componentWillReceiveProps: function (newProps) {
console.log(newProps)
},
render: function () {
return (<div> </div>);
}
});
module.exports = TodoModal;
I'm not familiar with Foundation Modal
but I believe the problem is with when you're setting up the modalMarkup
component.
According to the lifecycle of React components, componentDidMount
is only called once when the component is loaded. When you get new props via componentWillRecieveProps
, the componentDidMount
function is NOT re-invoked and therefore your modal is not referencing the new props.
Instead try to create the modal in both (if you can) componentDidMount
and componentWillReceiveProps
to handle the new props, maybe via a createModal(props)
function which you can pass in the relevant set of props.
I wish I could give you more information on how to create the modal but as I said I'm not familiar with Foundation Modal
.
You can read more about the lifecyle of the components here: Component Specs and Lifecycle
Updated in response to your comment
To pass new props to your TodoModal
component you simply need to change the value you're passing to the TodoModal
component's todo
property. For example lets assume you have a component called CompA
which is rendering CompB
and CompB
requires a property item
. CompA
's render may look like this:
CompA
render: function () {
return (<CompB item={this.props.myItem}/>);
}
But now lets say that CompB
can be provided new property values and defines the componentWillRecieveProps
function. The current setup would ONLY pass a prop to CompB
if CompA
's property myItem
was changed. You could technically do this but you could also do something like the following:
CompA
getInitialState: function () {
return {
item: this.props.myItem
};
},
render: function() {
// Use the state as the value for CompB's property
// Then changing the state will invoke CompB's componentWillReceiveProps function
return (<CompB item={this.state.item}/>);
}
Now in this case change CompA
's state will the new value to be passed to CompB
and then CompB
would receive it as a newly received props. You can make the state change be invoked by some event like a click, hover, whatever and you should have what you were asking about.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.