-
-
Notifications
You must be signed in to change notification settings - Fork 10.6k
Context Issues with <Link> #982
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I'm having a hard time understanding what you're trying to do and why you'd want to render like that. How does the rest of your app work? Generally speaking, I don't think it makes sense to load html from server, render it by setting innerHTML and then replacing several parts using React.render. You usually want to have a root element (e.g. document.body) where you render your whole React app, and then load data (not markup) via ajax to update the UI. |
@taurose Basically this is done in this way so users are able to edit what they are familiar with, HTML, on another part of the app, and then saving it so it displays on each page. |
I'm still not seeing the full picture. Do you have a top level React.render call inside Router.run? Why do you use react if your markup is (mostly?) static? Back to the problem: As far as I understand context, it's not preserved when you do another React.render (ie. context is bound to a "render tree" produced via a single React.render call, not to single components starting another render, or the DOM). The only reliable way to pass down context is via render() in components. Two ideas to work around that:
You may also have to manually rerender those links on every route change, if you want to use active classes. |
You're not going to get context there, is this code inside of react component that is inside of your app rendered in a var App = React.createClass({
contextTypes: {
router: React.PropTypes.func
},
componentDidMount () {
var router = this.context.router;
var NewLink = React.createClass({
childContextTypes: {
router: React.PropTypes.func
},
getChildContext () {
return {
router: router
}
}
render () {
return <Link {...this.props}/>;
}
});
fetchYourTemplateThing((tmp) => {
// do your stuff
React.render(<NewLink .../>, el);
});
}
}); |
I'm having a similar problem here. I built a custom stripped-down Here is the code for my Modal class: import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import styles from './Modal.scss';
class Modal extends Component {
_open() {
this._scrollY = window.scrollY;
this._mount = document.getElementById('mount');
this._modalContainer = document.createElement('div');
var animationListener = () => {
this._modalContainer.classList.add('modal-entered');
this._modalContainer.classList.remove('modal-enter');
this._mount.classList.add('hide');
this._modalContainer.removeEventListener('animationend', animationListener);
};
this._modalContainer.addEventListener('animationend', animationListener);
this._modalContainer.classList.add('modal');
document.body.appendChild(this._modalContainer);
this._modalContainer.classList.add('modal-enter');
}
_close() {
var animationListener = () => {
this._modalContainer.removeEventListener('animationend', animationListener, false);
ReactDOM.unmountComponentAtNode(this._modalContainer);
document.body.removeChild(this._modalContainer);
this._modalContainer = null;
};
this._modalContainer.addEventListener('animationend', animationListener, false);
this._mount.classList.remove('hide');
window.scrollTo(0, this._scrollY);
this._modalContainer.classList.add('modal-leave');
}
_render() {
if(this._modalContainer) {
let modal = (
<div className={this.props.classNames || ''}>
{this.props.children}
</div>
);
ReactDOM.render(modal, this._modalContainer);
}
}
componentDidUpdate() {
var open = this.props.open;
console.log(open);
if (open && !this._modalContainer) {
this._open();
}
if (!open && this._modalContainer) {
this._close();
}
this._render();
}
render() {
return null;
}
}
export default Modal; and the instance I'm passing in the link to: import React, {Component} from 'react'
import Modal from '../Modal/Modal';
import Avatar from '../Avatar/Avatar';
import styles from './BioModal.scss';
import Clear from 'material-ui/lib/svg-icons/content/clear';
import { Link } from 'react-router';
class BioModal extends Component {
render() {
var bio = this.props.bio || {};
var overview = bio.overview,
description;
if (overview) {
let overviewMarkup = () => {
return {
__html: overview
}
};
description = (
<div className={styles.description} dangerouslySetInnerHTML={overviewMarkup()}></div>
);
}
var bioTemplate = (
<div className={styles.content}>
<div className={styles.avatarContainer}>
<Avatar className={styles.avatar} src={`/public/${bio.fullSize}.jpg`} alt={bio.name}/>
</div>
<div className={styles.mainContent}>
<h1 className={styles.employeeName}>{bio.name}</h1>
{ description }
</div>
</div>
);
return (
<Modal open={this.props.open}>
<Link to="/about-us">
<Clear className={styles.closeButton} color={'#333'}/>
</Link>
{ bioTemplate }
</Modal>
)
}
}
export default BioModal; |
You can't just render modals like that into containers and preserve context. Use an existing modal library that handles this for you, or look into how to pass through context into subtrees. |
@dwilt Could you please share the final code with the context fix? :) |
@horgen sorry man, I don't have access to the code anymore as this was over a year ago :( |
I'm using React-Router in order to generate links to route to dynamically-generated routes in a dynamically generated template area. Here's the code:
`ajax('GET','/content/template/'+template+'/master.html',function(tmp){
document.getElementById('template').innerHTML = tmp;
});`
All is well, and works well, until the final line of code, namely:
React.render(<Link to={mitems[item].route}>{mitems[item].text}</Link>, getAllElementsWithAttribute('menu-name',mop[i].getAttribute('menu-name'))[0]);
where, as I have seen in #400, and #513, gives

From what I have seen, this is a bug with context, however there are no cloneWithProps() in my application, and nothing seems that out of the ordinary. Any help with workarounds would be appreciated
The text was updated successfully, but these errors were encountered: