Итак, я работаю над реактивным проектом. У меня есть текстовая область, в которую я ввожу данные, а затем эти данные хэшируются, а блок с номером блока, хэшированными данными и временем отображается на экране при каждом нажатии кнопки. Однако, когда я снова ввожу данные и снова нажимаю кнопку, он просто перерисовывает блок как блок номер 2. Я хочу, чтобы предыдущий блок оставался на экране, а новый блок отображался под предыдущим блоком всякий раз, когда я нажимаю кнопку. Как мне это решить? Я много пробовал, но ничего не работает. Я нахожусь на стадии изучения реакции, поэтому, пожалуйста, извините меня, если этот вопрос кажется тривиальным.
App.js
import React, {Component} from 'react';
import BlockList from './BlockList.js';
import InputText from './InputText.js';
import Button from './Button.js';
constructor() {
super();
console.info('constructor invoked')
this.state = {
blockno:0,
Data:'',
hash:'',
showDiv: false
}
onButtonClick = (event) => {
console.info('onButtonClick invoked')
this.setState({blockno: this.state.blockno + 1, showDiv: true})
}
}
render() {
return(
<div>
<InputText onSearchChange = {this.OnSearchChange}/>
<Button onButtonClick = {this.onButtonClick} />
{
this.state.showDiv
?
<div>
<BlockList blockno = {this.state.blockno} Data = {this.state.Data} />
</div>
: ''
}
</div>
);
}
}
export default App;
Block.js
import React from 'react';
import SHA256 from 'sha256-es';
const Block = ({blockno,Data}) => {
const hashdata = () =>{
return(
SHA256.hash(Data)
);
}
var today = new Date();
var dd = String(today.getDate()).padStart(2, '0');
var mm = String(today.getMonth() + 1).padStart(2, '0'); //January is 0!
var yyyy = today.getFullYear();
today = mm + '/' + dd + '/' + yyyy;
return(
<div className = "tc ws-pre">
<h1 className = "underline">Block {blockno}</h1>
<h2>Data: {Data}</h2>
<h2>Hash: {hashdata()}</h2>
<h2>Date: {today}</h2>
</div>
);
}
export default Block
BlockList.js
import React from 'react';
import Block from './Block.js';
const BlockList = ({blockno,Data,isBlockUpdated}) => {
const BlockItems = () => {
return(
<div>
{console.info('A block item is now returned')}
<Block blockno = {blockno} Data = {Data} />
</div>
);
}
return(
<div>
<BlockItems />
</div>
);
}
export default BlockList
Я хочу отображать новый блок под предыдущим каждый раз, когда я нажимаю кнопку.
Я только что бегло просмотрел. Таким образом, каждый раз, когда вы нажимаете кнопку в App.js, вы добавляете 1 к blockno
в состоянии. Это просто число, поэтому оно просто обновляется и передается в Block.js.
Если вы хотите отобразить несколько блоков, вам нужно создать массив, который вы можете перебирать и отображать компонент блока для каждого блока.
По сути, ваше состояние должно быть примерно таким:
blocks: [{ block data here }]
Затем onButtonClick необходимо добавить объект в этот массив. Затем вы можете передать этот массив в BlockList и перебрать его там.
BlockList выглядит примерно так:
{blocks.map(block => (
<Block data = {block.data} />
))}
Имеет ли это смысл?
Как ответ DanBonehill, вам нужен массив для хранения блоков
App.js
constructor() {
super();
console.info('constructor invoked')
this.state = {
// To store the list of blocks
blocks: [],
}
}
onButtonClick = (event) => {
console.info('onButtonClick invoked')
let blocks = this.state.blocks
// Create a new block with current data and time
blocks.push({data: this.state.Data, time: Date.time()})
this.setState({blocks})
}
render() {
// other stuff here
{
this.state.blocks.length > 0
?
<div>
<BlockList blocks = {this.state.blocks} />
</div>
: ''
}
}
BlockList.js
const BlockList = ({blocks,Data,isBlockUpdated}) => {
// other stuff here
return(
<div>
{blocks.map((block, index) => <BlockItem {...block} blockno = {index} />)}
</div>
);
}
ваш
BlockList
действительно имеет только один блок. У меня сейчас нет времени разбираться и набирать полный рабочий фрагмент кода, но вам нужно передать массив идентификаторов блоков этому компоненту (и добавлять к нему каждый раз, когда происходит соответствующее действие) , иmap
для рендеринга несколькихBlock
компонентов.