我偶尔会对概念上有状态的组件做出反应,我想重置它们.理想的行为相当于删除旧组件并读取新的原始组件.
React提供了一种方法setState,允许设置组件自己的显式状态,但不包括隐式状态,如浏览器焦点和表单状态,并且它还排除其子级的状态.抓住所有间接状态可能是一个棘手的任务,我宁愿严格而完全地解决它,而不是每一个令人惊讶的新状态都在玩捣蛋.
是否有API或模式来执行此操作?
编辑: 我做了一个简单的例子来演示这种this.replaceState(this.getInitialState())方法并将其与方法进行对比this.setState(this.getInitialState()):https://jsfiddle.net/emn13/kdrzk6gh/ - replaceState更强大.
我想从React Element的实例调用React组件公开的方法.
例如,在这个jsfiddle https://jsfiddle.net/r6r8cp3z/我想alertMessage从HelloElement引用中调用该方法.
有没有办法实现这一点,而无需编写额外的包装器?
编辑(从JSFiddle复制代码)
<div id="container"></div>
<button onclick="onButtonClick()">Click me!</button>
Run Code Online (Sandbox Code Playgroud)
var onButtonClick = function () {
//call alertMessage method from the reference of a React Element! Something like HelloElement.alertMessage()
console.log("clicked!");
}
var Hello = React.createClass({displayName: 'Hello',
alertMessage: function() {
alert(this.props.name);
},
render: function() {
return React.createElement("div", null, "Hello ", this.props.name);
}
});
var HelloElement = React.createElement(Hello, {name: "World"});
React.render(
HelloElement,
document.getElementById('container')
);
Run Code Online (Sandbox Code Playgroud) 例如:http://codepen.io/Enclave88/pen/YqNpog?edit = 1010
var InputBox = React.createClass({
render: function() {
return (
<input className="mainInput" value='Some something'></input>
)
}
});
Run Code Online (Sandbox Code Playgroud) 我想在React中的div上使用keyDown事件.我做:
componentWillMount() {
document.addEventListener("keydown", this.onKeyPressed.bind(this));
}
componentWillUnmount() {
document.removeEventListener("keydown", this.onKeyPressed.bind(this));
}
onKeyPressed(e) {
console.log(e.keyCode);
}
render() {
let player = this.props.boards.dungeons[this.props.boards.currentBoard].player;
return (
<div
className="player"
style={{ position: "absolute" }}
onKeyDown={this.onKeyPressed} // not working
>
<div className="light-circle">
<div className="image-wrapper">
<img src={IMG_URL+player.img} />
</div>
</div>
</div>
)
}
Run Code Online (Sandbox Code Playgroud)
它工作正常,但我想在React风格中做得更多.我试过了
onKeyDown={this.onKeyPressed}
Run Code Online (Sandbox Code Playgroud)
在组件上.但它没有反应.我记得它适用于输入元素.
Codepen:http://codepen.io/lafisrap/pen/OmyBYG
我该怎么做?
我一直在收到错误:
"路由器"可能只有一个子元素
当使用react-router时.
我似乎无法弄清楚为什么这不起作用,因为它与他们在示例中显示的代码完全相同:https://reacttraining.com/react-router/web/guides/quick-start
这是我的代码:
import React from 'react';
import Editorstore from './Editorstore';
import App from './components/editor/App';
import BaseLayer from './components/baselayer';
import {BrowserRouter as Router, Route} from 'react-router-dom';
import {render} from 'react-dom';
const root = document.createElement('div');
root.id = 'app';
document.body.appendChild(root);
const store = new Editorstore();
const stylelist = ['https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css', 'https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.2/semantic.min.css', 'https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css', 'https://api.tiles.mapbox.com/mapbox-gl-js/v0.33.1/mapbox-gl.css'];
stylelist.map((link) => {
const a = document.createElement('link');
a.rel = 'stylesheet';
a.href = link;
document.body.appendChild(a);
return null;
});
render((
<Router>
<Route exact path="/" component={BaseLayer} />
<Route …Run Code Online (Sandbox Code Playgroud) 我可能遗漏了一些非常明显的东西,想要清除自己.
这是我的理解.
在一个天真的反应组件中,我们有states&props.state通过setState重新渲染更新整个组件.props大部分是只读的,更新它们没有意义.
在通过类似的方式订阅redux商店的react组件中store.subscribe(render),它显然会在每次更新商店时重新呈现.
react-redux有一个帮助器connect(),它注入部分状态树(组件感兴趣)和actionCreators props关于组件,通常通过类似的方式
const TodoListComponent = connect(
mapStateToProps,
mapDispatchToProps
)(TodoList)
Run Code Online (Sandbox Code Playgroud)
但是要理解a setState对于对TodoListComponentredux状态树更改(重新渲染)做出反应是必不可少的,我在组件文件中找不到任何state或setState相关的代码TodoList.它读起来像这样:
const TodoList = ({ todos, onTodoClick }) => (
<ul>
{todos.map(todo =>
<Todo
key={todo.id}
{...todo}
onClick={() => onTodoClick(todo.id)}
/>
)}
</ul>
)
Run Code Online (Sandbox Code Playgroud)
有人能指出我正确的方向,我错过了什么?
PS我正在关注与redux包捆绑在一起的todo list示例(https://github.com/reactjs/redux/tree/master/examples/todos/src/containers).
我一直在寻找一些帮助来制作一个组件来帮助管理从React内部上传文件到我设置的端点.
我尝试过很多选项,包括整合http://filedropjs.org.我决定反对它,因为我无法控制它在DOM中设置的元素new FileDrop('zone', options);
这是我到目前为止:
module.exports = React.createClass({
displayName: "Upload",
handleChange: function(e){
formData = this.refs.uploadForm.getDOMNode();
jQuery.ajax({
url: 'http://example.com',
type : 'POST',
xhr: function(){
var myXhr = $.ajaxSettings.xhr();
if(myXhr.upload){
myXhr.upload.addEventListener('progress',progressHandlingFunction, false);
}
return myXhr;
},
data: formData,
cache: false,
contentType: false,
processData: false,
success: function(data){
alert(data);
}
});
},
render: function(){
return (
<form ref="uploadForm" className="uploader" encType="multipart/form-data" onChange={this.handleChange}>
<input ref="file" type="file" name="file" className="upload-file"/>
</form>
);
}
});
},
render: function(){
console.log(this.props.content);
if(this.props.content != ""){
return (
<img src={this.props.content} …Run Code Online (Sandbox Code Playgroud) 这就是我在做的事:http://jsfiddle.net/iamnoah/pTrrw/
关键部分是:
position: function() {
var container = $(this.getDOMNode());
this._menu = $(this.refs.menu.getDOMNode());
this._menu.appendTo(document.body).
offset({
top: container.offset().top +
container.outerHeight(),
left: container.offset().left
});
},
restore: function() {
this._menu.appendTo(this.getDOMNode());
},
componentWillUpdate: function() {
this.restore();
},
componentDidUpdate: function() {
this.position();
},
componentDidMount: function() {
this.position();
},
Run Code Online (Sandbox Code Playgroud)
这个现在很好用.我假设React在更新之间单独留下DOM并且不会错过它,我会在组件更新之前将内容放回去.事实上,React似乎可以正常移动内容(如果我删除componentWillUpdate并且componentDidUpdate定位的元素仍然更新!)
我的问题是有多少结果假设是安全的(即,如果我假设这些东西,我的代码是否会在未来版本的React中破坏?):
componentWillUpdate.对我来说,最后一个看起来有点极端和神奇,但如果它成立,它会有一些很大的影响.
我注意到reactDOM.renderToString()在服务器上渲染大型组件树时,该方法开始显着减慢.
一点背景.该系统是一个完全同构的堆栈.最高级别的App组件呈现模板,页面,dom元素和更多组件.查看反应代码,我发现它渲染了~1500个组件(这包括任何简单的dom标记,它被视为一个简单的组件,<p>this is a react component</p>.
在开发中,渲染~1500个组件需要大约200-300ms.通过删除一些组件,我能够在~175-225ms内获得~1200个组件.
在生产中,〜1500个组件上的renderToString大约需要50-200ms.
时间似乎是线性的.没有一个组件是慢的,而是它的总和.
这会在服务器上产生一些问题.冗长的方法导致服务器响应时间过长.TTFB比它应该高很多.使用api调用和业务逻辑,响应应该是250ms,但是使用250ms renderToString它会加倍!SEO和用户不好.此外,作为同步方法,renderToString()可以阻止节点服务器并备份后续请求(这可以通过使用2个单独的节点服务器来解决:1作为Web服务器,1作为服务来单独呈现反应).
理想情况下,生产中需要5-50ms的renderToString.我一直在研究一些想法,但我不确定最好的方法是什么.
任何标记为"静态"的组件都可以缓存.通过使用呈现的标记保持缓存,renderToString()可以在呈现之前检查缓存.如果找到一个组件,它会自动抓取该字符串.在高级组件中执行此操作将保存所有嵌套子组件的安装.您必须使用当前的rootID替换缓存的组件标记的反应rootID.
通过将组件定义为"简单",react应该能够在呈现时跳过所有生命周期方法.反应已经这样做了芯反应,DOM组件(<p/>,<h1/>,等).很高兴扩展自定义组件以使用相同的优化.
服务器上不需要返回的组件(没有SEO值)可以简单地跳过.客户端加载后,设置一个clientLoaded标志true并将其传递给强制重新渲染.
到目前为止,我实现的唯一解决方案是减少服务器上呈现的组件数量.
我们正在研究的一些项目包括:
有人遇到过类似的问题吗?你有什么能做的?谢谢.
performance render-to-string reactjs isomorphic-javascript react-dom
我一直在关注ReduxJS文档:http://redux.js.org/docs/basics/UsageWithReact.html
在文档的最后,它提到了提供者对象的使用,我已经将我的App组件包装在提供者中,如下所示:
import React from 'react'
import ReactDOM from 'react-dom'
import { createStore } from 'redux'
import { Provider } from 'react-redux'
import RootReducer from './app/reducers'
import App from './app/app'
const store = createStore(RootReducer)
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
Run Code Online (Sandbox Code Playgroud)
但是,这就是文档结束的地方.如何在组件内拾取提供商提供的商店?
reactjs ×10
javascript ×3
redux ×2
ajax ×1
dom ×1
events ×1
input ×1
jquery ×1
keydown ×1
keypress ×1
performance ×1
react-dom ×1
react-redux ×1
react-router ×1
select ×1