Javascript ReactJS:单击时动态添加组件
我有一个菜单按钮,按下时必须添加一个新的组件。它似乎可以工作(如果我手动调用函数来添加显示的组件)。问题是,如果我单击按钮,它们不会显示,我想是因为我应该使用setState重新绘制它们。我不知道如何在另一个函数/组件中调用另一个组件的setState 这是我的index.jsJavascript ReactJS:单击时动态添加组件,javascript,reactjs,components,dynamically-generated,Javascript,Reactjs,Components,Dynamically Generated,我有一个菜单按钮,按下时必须添加一个新的组件。它似乎可以工作(如果我手动调用函数来添加显示的组件)。问题是,如果我单击按钮,它们不会显示,我想是因为我应该使用setState重新绘制它们。我不知道如何在另一个函数/组件中调用另一个组件的setState 这是我的index.js import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import Menu from './Menu';
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import Menu from './Menu';
import * as serviceWorker from './serviceWorker';
import Blocks from './Block.js';
ReactDOM.render(
<div className="Main-container">
<Menu />
<Blocks />
</div>
, document.getElementById('root'));
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers:
serviceWorker.unregister();
从“React”导入React;
从“react dom”导入react dom;
导入“./index.css”;
从“./菜单”导入菜单;
将*作为serviceWorker从“/serviceWorker”导入;
从“/Block.js”导入块;
ReactDOM.render(
,document.getElementById('root');
//如果你想让你的应用程序离线工作并更快地加载,你可以更改
//取消注册()以在下面注册()。注意,这有一些陷阱。
//了解有关服务人员的更多信息:
serviceWorker.unregister();
然后我有了Menu.js
import React from 'react';
import './Menu.css';
import {blocksHandler} from './Block.js';
class Menu extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleAdd = this.handleAdd.bind(this);
}
handleAdd(event) {
blocksHandler.add('lol');
console.log(blocksHandler.render());
}
render() {
return (
<div className="Menu">
<header className="Menu-header">
<button className="Menu-button" onClick={this.handleAdd}>Add block</button>
</header>
</div>
);
}
}
export default Menu;
从“React”导入React;
导入“/Menu.css”;
从'./Block.js'导入{blocksHandler};
类菜单扩展了React.Component{
建造师(道具){
超级(道具);
this.state={value:''};
this.handleAdd=this.handleAdd.bind(this);
}
手持式(活动){
blocksHandler.add('lol');
log(blocksHandler.render());
}
render(){
返回(
添加块
);
}
}
导出默认菜单;
最后是Block.js
import React from 'react';
import './Block.css';
// this function adds components to an array and returns them
let blocksHandler = (function() {
let blocks = [];
return {
add: function(block) {
blocks.push(block);
},
render: function() {
return blocks;
}
}
})();
class Block extends React.Component {
constructor(props) {
super(props);
this.state = {
title: '',
content: ''
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({[event.target.name]: event.target.value});
}
handleSubmit(event) {
alert('A name was submitted: ' + this.state.title);
event.preventDefault();
}
render() {
return (
<div className="Block-container">
<form onSubmit={this.handleSubmit}>
<div className="Block-title">
<label>
Block title:
<input type="text" name="title" value={this.state.value} onChange={this.handleChange} />
</label>
</div>
<div className="Block-content">
<label>
Block content:
<input type="text" name="content" value={this.state.value} onChange={this.handleChange} />
</label>
</div>
<input type="submit" value="Save" />
</form>
</div>
);
}
}
class Blocks extends React.Component {
render() {
return (
<div>
{blocksHandler.render().map(i => (
<Block key={i} />
))}
</div>
)
}
}
export default Blocks;
export {blocksHandler};
从“React”导入React;
导入“/Block.css”;
//此函数用于将组件添加到数组并返回它们
让blocksHandler=(函数(){
设块=[];
返回{
添加:功能(块){
推(块);
},
render:function(){
返回块;
}
}
})();
类块扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
标题:“”,
内容:“”
};
this.handleChange=this.handleChange.bind(this);
this.handleSubmit=this.handleSubmit.bind(this);
}
手变(活动){
this.setState({[event.target.name]:event.target.value});
}
handleSubmit(事件){
警报(“已提交名称:”+this.state.title);
event.preventDefault();
}
render(){
返回(
标题栏:
块内容:
);
}
}
类块扩展了React.Component{
render(){
返回(
{blocksHandler.render().map(i=>(
))}
)
}
}
导出默认块;
出口{blocksHandler};
我是一个完全的初学者,所以我甚至不确定我的方法是否正确。感谢您提供的帮助。您可以在Menu.js中使用BlockShandler,而不是将其作为单独的函数创建,如下所示 *
类块扩展React.Component{
建造师(道具){
超级(道具);
此.state={
标题:“”,
内容:“”
};
this.handleChange=this.handleChange.bind(this);
this.handleSubmit=this.handleSubmit.bind(this);
}
手变(活动){
this.setState({[event.target.name]:event.target.value});
}
handleSubmit(事件){
警报(“已提交名称:”+this.state.title);
event.preventDefault();
}
render(){
返回(
标题栏:
块内容:
);
}
}
Menu.js
class Menu extends React.Component {
constructor(props) {
super(props);
this.state = {value: '',blocksArray:[]};
this.handleAdd = this.handleAdd.bind(this);
}
handleAdd() {
this.setState({
blocksArray:this.state.blocksArray.push(block)
})
}
renderBlocks = ()=>{
this.state.blocksArray.map(block=> <Block/>)
}
render() {
return (
<div className="Menu">
<header className="Menu-header">
<button className="Menu-button" onClick={()=>this.handleAdd()}>Add block</button>
</header>
{this.renderBlocks()}
</div>
);
}
}
export default Menu;
类菜单扩展了React.Component{
建造师(道具){
超级(道具);
this.state={value:'',blocksArray:[]};
this.handleAdd=this.handleAdd.bind(this);
}
handleAdd(){
这是我的国家({
blocksArray:this.state.blocksArray.push(block)
})
}
renderBlocks=()=>{
this.state.blocksArray.map(block=>)
}
render(){
返回(
this.handleAdd()}>添加块
{this.renderBlocks()}
);
}
}
导出默认菜单;
下面,我构建了一个非常简单的父/子类型设置
父级负责呈现按钮,我在这里使用了一个简单的编号数组。当您单击任何按钮时,它将调用父级中的setState,这将导致父级重新渲染其子级
注意:我也使用了React钩子来实现这一点,我只是发现它们更多
自然和易于使用。您可以使用类,原理相同
适用
const{useState}=React;
功能儿童(道具){
const{caption}=props;
const{lines,setLines}=props.pstate;
返回{
设置行([…行,行.长度]);
}}>
{标题}
;
}
函数父级(道具){
常量[lines,setLines]=useState([0]);
返回行.map(m=>);
}
ReactDOM.render(
,document.querySelector('mount')代码>
您可以使用道具将父级状态传递给子级,。如果将道具传递给子级包含许多子组件,则还可以使用上下文传递道具。最好的解决方案是根本不使用React state,而使用一个更健壮的状态管理系统,Redux就是为了实现这一点。谢谢你的帖子。我正在尝试学习ReactJS,添加Redux可能会让事情变得太复杂。我会查看你的链接。是的,如果你只是学习,使用Redux可能会混淆事情,。。我可能会给你一个非常简单的片段,也许会对你有所帮助
class Menu extends React.Component {
constructor(props) {
super(props);
this.state = {value: '',blocksArray:[]};
this.handleAdd = this.handleAdd.bind(this);
}
handleAdd() {
this.setState({
blocksArray:this.state.blocksArray.push(block)
})
}
renderBlocks = ()=>{
this.state.blocksArray.map(block=> <Block/>)
}
render() {
return (
<div className="Menu">
<header className="Menu-header">
<button className="Menu-button" onClick={()=>this.handleAdd()}>Add block</button>
</header>
{this.renderBlocks()}
</div>
);
}
}
export default Menu;