reactjs - 有没有办法从 React 中的 render 函数中取出定义在 render 中的代码?
问题描述
我在渲染函数中编写了一个函数。当我在返回中调用它时,它可以工作。但现在我想做的就是把它拿出来放在渲染之前。有没有办法做到这一点?我已经给出了下面的函数。在这里我评论的是我想要得到的最终输出
import React from 'react';
import { Row, Col, Form, FormGroup, Input, Label } from 'reactstrap';
import * as Icon from 'react-bootstrap-icons';
import ReactQuill from 'react-quill';
import ActionButton from '../../components/ActionButton/ActionButton';
import InputFieldWithImage from '../../components/InputFieldWithImage/InputFieldWithImage';
import SelectedFilesDisplayLabel from '../../components/SelectedFilesDisplayLabel/SelectedFilesDisplayLabel';
import DropDown from '../../components/DropDown/DropDown';
import CustomToolbar from '../../components/EditorToolbar/EditorToolbar';
import 'react-quill/dist/quill.snow.css';
import './Popup.scss';
import Amy from './../../assets/images/Amy.png';
const icons = ReactQuill.Quill.import('ui/icons');
icons['link'] = <Icon.Link />;
class AddTicket extends React.Component {
constructor(props) {
super(props);
this.state = {
selectedFile: null,
title: '',
description: '',
assignee: '',
employer: '',
type: 'A',
priority: 'Top',
edit: '',
text: '',
editorHtml: '',
uploadedFileName: '',
uploadedFileType: '',
flagPdf: false,
flagImage: false,
flagDoc: false,
selectedFiles: [],
dropdownOpen: false,
isOpen: false,
typeArray: ['A', 'B', 'C', 'D'],
priorityArray: ['Top', 'Middle', 'Least', 'No']
};
}
// This is the function for file upload.Here it checks whether there is the same file already attached
// and if not stored in selectedFiles array.Flag is used here in the function to keep the state of the file
// whether there contain a file with same name.
handleChangeFile = (event) => {
let fileExists;
let temp = [];
let files = [];
let tempSelectedFilesArr = this.state.selectedFiles;
for (let i = 0; i < event.target.files.length; i++) {
let file = event.target.files[i];
if (
file.type === 'application/pdf' ||
file.type === 'image/png' ||
file.type === 'image/jpeg' ||
file.type === 'application/msword' ||
file.type ===
'application/vnd.openxmlformats-officedocument.wordprocessingml.document' ||
file.type === 'video/mp4'
) {
files.push(file);
}
}
if (tempSelectedFilesArr.length > 0) {
for (let i = 0; i < files.length; i++) {
fileExists = 0;
for (let j = 0; j < tempSelectedFilesArr.length; j++) {
if (files[i].name === tempSelectedFilesArr[j].name) {
fileExists = 1;
break;
}
}
if (fileExists === 0) {
temp.push(files[i]);
}
}
} else {
for (let i = 0; i < files.length; i++) {
temp.push(files[i]);
}
}
this.setState({
selectedFiles: tempSelectedFilesArr.concat(temp)
});
};
// This handles text which input to title,assignee and employee
handleChangeInputs = (event) => {
this.setState({
[event.target.name]: event.target.value
});
};
// In this function, text which are input into the descripion box ,are stored in the state
handleDescription = (html) => {
this.setState({ editorHtml: html });
};
// These two function handleType,handlePriority are send as props to the dropdown component.
handleType = (e) => {
this.setState({ type: e.currentTarget.textContent });
};
handlePriority = (e) => {
this.setState({ priority: e.currentTarget.textContent });
};
// This function handle all the input values. Values are send to the backend from this
handleSubmit = (event) => {
event.preventDefault();
console.log(this.state.title);
console.log(this.state.type);
console.log(this.state.priority);
console.log(this.state.assignee);
console.log(this.state.employer);
this.props.handleClose();
};
// Uploaded files are displayed in the screen. After clicking the close button,
// this function calls
cardClose(value) {
let temp = this.state.selectedFiles.filter((n) => {
return n.name !== value;
});
this.setState({
selectedFiles: temp
});
}
// These are used in the react quill component.
static modules = {
toolbar: {
container: '#toolbar'
}
};
// decription = this.state.selectedFiles.map((item, key) => {
// let size = item.size / 1048576;
// size = size.toFixed(2);
// const K = item.name;
// return (
// <div>
// {item.type === 'application/pdf' && (
// <SelectedFilesDisplayLabel
// onClick={() => {
// this.cardClose(K);
// }}
// name={item.name}
// size={size}
// icon={<Icon.FileEarmarkText />}
// />
// )}
// {item.type === 'image/png' && (
// <SelectedFilesDisplayLabel
// onClick={() => {
// this.cardClose(K);
// }}
// name={item.name}
// size={size}
// icon={<Icon.Image />}
// />
// )}
// {item.type === 'image/jpeg' && (
// <SelectedFilesDisplayLabel
// onClick={() => {
// this.cardClose(K);
// }}
// name={item.name}
// size={size}
// icon={<Icon.Image />}
// />
// )}
// {item.type === 'application/msword' && (
// <SelectedFilesDisplayLabel
// onClick={() => {
// this.cardClose(K);
// }}
// name={item.name}
// size={size}
// icon={<Icon.FileEarmarkText />}
// />
// )}
// {item.type ===
// 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' && (
// <SelectedFilesDisplayLabel
// onClick={() => {
// this.cardClose(K);
// }}
// name={item.name}
// size={size}
// icon={<Icon.FileEarmarkText />}
// />
// )}
// {item.type === 'video/mp4' && (
// <SelectedFilesDisplayLabel
// onClick={() => {
// this.cardClose(K);
// }}
// name={item.name}
// size={size}
// icon={<Icon.Film />}
// />
// )}
// </div>
// );
// });
render() {
let fileUploader = React.createRef();
const decription = this.state.selectedFiles.map((item, key) => {
let size = item.size / 1048576;
size = size.toFixed(2);
const K = item.name;
return (
<div>
{item.type === 'application/pdf' && (
<SelectedFilesDisplayLabel
onClick={() => {
this.cardClose(K);
}}
name={item.name}
size={size}
icon={<Icon.FileEarmarkText />}
/>
)}
{item.type === 'image/png' && (
<SelectedFilesDisplayLabel
onClick={() => {
this.cardClose(K);
}}
name={item.name}
size={size}
icon={<Icon.Image />}
/>
)}
{item.type === 'image/jpeg' && (
<SelectedFilesDisplayLabel
onClick={() => {
this.cardClose(K);
}}
name={item.name}
size={size}
icon={<Icon.Image />}
/>
)}
{item.type === 'application/msword' && (
<SelectedFilesDisplayLabel
onClick={() => {
this.cardClose(K);
}}
name={item.name}
size={size}
icon={<Icon.FileEarmarkText />}
/>
)}
{item.type ===
'application/vnd.openxmlformats-officedocument.wordprocessingml.document' && (
<SelectedFilesDisplayLabel
onClick={() => {
this.cardClose(K);
}}
name={item.name}
size={size}
icon={<Icon.FileEarmarkText />}
/>
)}
{item.type === 'video/mp4' && (
<SelectedFilesDisplayLabel
onClick={() => {
this.cardClose(K);
}}
name={item.name}
size={size}
icon={<Icon.Film />}
/>
)}
</div>
);
});
return (
<div className="popup-box">
<div className="box">
<Form onSubmit={this.handleSubmit} className="form">
{' '}
<div className="form-close-icon">
<Icon.X />
</div>
<Row className="form-row">
<Col xs={11}>
<h1 className="heading">Add new ticket </h1>
</Col>
<Col xs={1} onClick={this.props.handleClose}></Col>
</Row>
<FormGroup>
<Row className="title">
<Col xs={2} className="title-align-one">
<h4>Title</h4>
</Col>
<Col xs={4}>
<Input
type="text"
name="title"
id="title"
value={this.state.title}
onChange={this.handleChangeInputs}
className="input-field"
placeholder="Title of the ticket"
/>
</Col>
</Row>
</FormGroup>
<FormGroup>
<Row className="title">
<Col xs={2} className="title-align-two">
<h4>Description</h4>
</Col>
<Col xs={9}>
<div>
<div className="text-box">
<div className="editor-wrapper">
<div className="editor-container">
<div className="text-editor">
<ReactQuill
value={this.state.editorHtml}
onChange={this.handleDescription}
placeholder={this.props.placeholder}
modules={AddTicket.modules}
formats={AddTicket.formats}
/>
<div className="display-cards">{decription}</div>
<div id="toolbar">
<CustomToolbar onInput={this.handleChangeFile} />
</div>
</div>
</div>
</div>
</div>
</div>
</Col>
</Row>
</FormGroup>
<FormGroup>
<Row className="title-type">
<Col xs={2} className="title-align-two">
<h4>Type </h4>
</Col>
<Col xs={10}>
<DropDown
onClick={this.handleType}
dropDwonItemArray={this.state.typeArray}
text={this.state.type}
/>
</Col>
</Row>
</FormGroup>
<FormGroup>
<Row className="title">
<Col xs={2} className="title-align-two">
<h4>Priority </h4>
</Col>
<Col xs={10}>
<DropDown
onClick={this.handlePriority}
dropDwonItemArray={this.state.priorityArray}
text={this.state.priority}
/>
</Col>
</Row>
</FormGroup>
<FormGroup>
<Row className="title">
<Col sm={2} className="title-align-one">
<h4>Assignee</h4>
</Col>
<Col sm={4} className="imageAssigneeCol">
<InputFieldWithImage
value={this.state.assignee}
onChange={this.handleChangeInputs}
picture={Amy}
className="field-image"
/>
</Col>
</Row>
</FormGroup>
<FormGroup>
<Row className="title">
<Col xs={2} className="title-align-one">
<h4 className="title-employer">Employer</h4>
<Label className="text-optional">Optional</Label>
</Col>
<Col xs={4}>
<Input
type="text"
name="employer"
id="employer"
value={this.state.employer}
onChange={this.handleChangeInputs}
className="input-field-employee"
/>
</Col>
</Row>
</FormGroup>
<FormGroup>
<Row>
<Col xs={4} className="submit-button">
<ActionButton text="Send" />
</Col>
</Row>
</FormGroup>
</Form>
</div>
</div>
);
}
}
export default AddTicket;
这就是我在返回函数中使用它的方式
<div className="display-cards">{decription}</div>
解决方案
您可以在 render() 函数之前定义 decriction,如下所示。
decription = () => (
<>
{
// Start .map function
this.state.selectedFiles.map((item, key) => {
let size = item.size / 1048576;
size = size.toFixed(2);
const K = item.name;
return (
<div>
{item.type === 'application/pdf' && (
<SelectedFilesDisplayLabel
onClick={() => {
this.cardClose(K);
}}
name={item.name}
size={size}
icon={<Icon.FileEarmarkText />}
/>
)}
{item.type === 'image/png' && (
<SelectedFilesDisplayLabel
onClick={() => {
this.cardClose(K);
}}
name={item.name}
size={size}
icon={<Icon.Image />}
/>
)}
{item.type === 'image/jpeg' && (
<SelectedFilesDisplayLabel
onClick={() => {
this.cardClose(K);
}}
name={item.name}
size={size}
icon={<Icon.Image />}
/>
)}
{item.type === 'application/msword' && (
<SelectedFilesDisplayLabel
onClick={() => {
this.cardClose(K);
}}
name={item.name}
size={size}
icon={<Icon.FileEarmarkText />}
/>
)}
{item.type ===
'application/vnd.openxmlformats-officedocument.wordprocessingml.document' && (
<SelectedFilesDisplayLabel
onClick={() => {
this.cardClose(K);
}}
name={item.name}
size={size}
icon={<Icon.FileEarmarkText />}
/>
)}
{item.type === 'video/mp4' && (
<SelectedFilesDisplayLabel
onClick={() => {
this.cardClose(K);
}}
name={item.name}
size={size}
icon={<Icon.Film />}
/>
)}
</div>
);
})
// End .map function
}
</>
)
并在 render() 的 div 中使用
<div className="display-cards">{this.decription()}</div>
在这里,你要知道 this.decription 和 this.decription() 的区别很重要...
推荐阅读
- javascript - Javascript 线程安全
- vue.js - 更改 Nuxt 进度条的位置
- ansible - Ansible 'assert' 模块和 '"changed": false'
- .htaccess - 带有随机数的 Htaccess 重定向
- javascript - 从另一个变量的子数组中获取数据
- asp.net-core - .Net Core API 方法未调用
- javascript - 在 Vuex 突变中使用 `Vue.nextTick` 是否违反惯例?它会破坏一些东西吗?
- javascript - 在 Firefox 浏览器中默认滚动到 div 的底部
- deployment - NetSuite 自定义模块入口点错误?
- unity3d - “警告日志”会影响 Unity3D 中的应用程序性能吗?