Каков самый простой способ выполнить простой Javascript в файле React 16 .js?
Ниже представлен блок рендеринга из файла React (назовите его myfile.js; весь файл приведен ниже).
Как я могу получить, т.е.
console.info;
или т.е.,
var timestamp = Math.round((new Date()).getTime() / 1000);
(или другой простой Javascript) для выполнения?
Нужно ли использовать const?
Лучше ли использовать большую часть Javascript вне блока рендеринга?
render () {
const { columns, children, singleColumn, isModalOpen } = this.props;
const { renderComposePanel } = this.state;
if (singleColumn) {
return (
<div className='columns-area__panels'>
<div className='columns-area__panels__pane columns-area__panels__pane--compositional'>
<div className='columns-area__panels__pane__inner'>
{renderComposePanel && <ComposePanel />}
</div>
</div>
<div className='columns-area__panels__main'>
<div className='tabs-bar__wrapper'><div id='tabs-bar__portal' />
console.info('Hello World''); // execute plain JS here
var timestamp = Math.round((new Date()).getTime() / 1000);
</div>
<div className='columns-area columns-area--mobile'>{children}</div>
</div>
<div className='columns-area__panels__pane columns-area__panels__pane--start columns-area__panels__pane--navigational'>
<div className='columns-area__panels__pane__inner'>
<NavigationPanel />
</div>
</div>
</div>
);
}
return (
<div className = {`columns-area ${ isModalOpen ? 'unscrollable' : '' }`} ref = {this.setRef}>
{columns.map(column => {
const params = column.get('params', null) === null ? null : column.get('params').toJS();
const other = params && params.other ? params.other : {};
return (
<BundleContainer key = {column.get('uuid')} fetchComponent = {componentMap[column.get('id')]} loading = {this.renderLoading(column.get('id'))} error = {this.renderError}>
{SpecificComponent => <SpecificComponent columnId = {column.get('uuid')} params = {params} multiColumn {...other} />}
</BundleContainer>
);
})}
{React.Children.map(children, child => React.cloneElement(child, { multiColumn: true }))}
</div>
);
}
}
Целиком myfile.js :
import React from 'react';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import BundleContainer from '../containers/bundle_container';
import ColumnLoading from './column_loading';
import DrawerLoading from './drawer_loading';
import BundleColumnError from './bundle_column_error';
import {
Compose,
Notifications,
HomeTimeline,
CommunityTimeline,
PublicTimeline,
HashtagTimeline,
DirectTimeline,
FavouritedStatuses,
BookmarkedStatuses,
ListTimeline,
Directory,
} from '../../ui/util/async-components';
import ComposePanel from './compose_panel';
import NavigationPanel from './navigation_panel';
import { supportsPassiveEvents } from 'detect-passive-events';
import { scrollRight } from '../../../scroll';
const componentMap = {
'COMPOSE': Compose,
'HOME': HomeTimeline,
'NOTIFICATIONS': Notifications,
'PUBLIC': PublicTimeline,
'REMOTE': PublicTimeline,
'COMMUNITY': CommunityTimeline,
'HASHTAG': HashtagTimeline,
'DIRECT': DirectTimeline,
'FAVOURITES': FavouritedStatuses,
'BOOKMARKS': BookmarkedStatuses,
'LIST': ListTimeline,
'DIRECTORY': Directory,
};
export default class ColumnsArea extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object.isRequired,
};
static propTypes = {
columns: ImmutablePropTypes.list.isRequired,
isModalOpen: PropTypes.bool.isRequired,
singleColumn: PropTypes.bool,
children: PropTypes.node,
};
// Corresponds to (max-width: $no-gap-breakpoint + 285px - 1px) in SCSS
mediaQuery = 'matchMedia' in window && window.matchMedia('(max-width: 1174px)');
state = {
renderComposePanel: !(this.mediaQuery && this.mediaQuery.matches),
}
componentDidMount() {
if (!this.props.singleColumn) {
this.node.addEventListener('wheel', this.handleWheel, supportsPassiveEvents ? { passive: true } : false);
}
if (this.mediaQuery) {
if (this.mediaQuery.addEventListener) {
this.mediaQuery.addEventListener('change', this.handleLayoutChange);
} else {
this.mediaQuery.addListener(this.handleLayoutChange);
}
this.setState({ renderComposePanel: !this.mediaQuery.matches });
}
this.isRtlLayout = document.getElementsByTagName('body')[0].classList.contains('rtl');
}
componentWillUpdate(nextProps) {
if (this.props.singleColumn !== nextProps.singleColumn && nextProps.singleColumn) {
this.node.removeEventListener('wheel', this.handleWheel);
}
}
componentDidUpdate(prevProps) {
if (this.props.singleColumn !== prevProps.singleColumn && !this.props.singleColumn) {
this.node.addEventListener('wheel', this.handleWheel, supportsPassiveEvents ? { passive: true } : false);
}
}
componentWillUnmount () {
if (!this.props.singleColumn) {
this.node.removeEventListener('wheel', this.handleWheel);
}
if (this.mediaQuery) {
if (this.mediaQuery.removeEventListener) {
this.mediaQuery.removeEventListener('change', this.handleLayoutChange);
} else {
this.mediaQuery.removeListener(this.handleLayouteChange);
}
}
}
handleChildrenContentChange() {
if (!this.props.singleColumn) {
const modifier = this.isRtlLayout ? -1 : 1;
this._interruptScrollAnimation = scrollRight(this.node, (this.node.scrollWidth - window.innerWidth) * modifier);
}
}
handleLayoutChange = (e) => {
this.setState({ renderComposePanel: !e.matches });
}
handleWheel = () => {
if (typeof this._interruptScrollAnimation !== 'function') {
return;
}
this._interruptScrollAnimation();
}
setRef = (node) => {
this.node = node;
}
renderLoading = columnId => () => {
return columnId === 'COMPOSE' ? <DrawerLoading /> : <ColumnLoading multiColumn />;
}
renderError = (props) => {
return <BundleColumnError multiColumn errorType='network' {...props} />;
}
render () {
const { columns, children, singleColumn, isModalOpen } = this.props;
const { renderComposePanel } = this.state;
if (singleColumn) {
return (
<div className='columns-area__panels'>
<div className='columns-area__panels__pane columns-area__panels__pane--compositional'>
<div className='columns-area__panels__pane__inner'>
{renderComposePanel && <ComposePanel />}
</div>
</div>
<div className='columns-area__panels__main'>
<div className='tabs-bar__wrapper'><div id='tabs-bar__portal' /></div>
<div className='columns-area columns-area--mobile'>{children}</div>
</div>
<div className='columns-area__panels__pane columns-area__panels__pane--start columns-area__panels__pane--navigational'>
<div className='columns-area__panels__pane__inner'>
<NavigationPanel />
</div>
</div>
</div>
);
}
return (
<div className = {`columns-area ${ isModalOpen ? 'unscrollable' : '' }`} ref = {this.setRef}>
{columns.map(column => {
const params = column.get('params', null) === null ? null : column.get('params').toJS();
const other = params && params.other ? params.other : {};
return (
<BundleContainer key = {column.get('uuid')} fetchComponent = {componentMap[column.get('id')]} loading = {this.renderLoading(column.get('id'))} error = {this.renderError}>
{SpecificComponent => <SpecificComponent columnId = {column.get('uuid')} params = {params} multiColumn {...other} />}
</BundleContainer>
);
})}
{React.Children.map(children, child => React.cloneElement(child, { multiColumn: true }))}
</div>
);
}
}
@LajosArpad Спасибо, но я не знаю, как это сделать.
@RandyCasburn Спасибо, я новичок в React, но немного знаю Javascript. Это выражение похоже на это: { 'hello' + 'world'; } ? Или (может быть, это другой вопрос) мне лучше добавить свой Javascript во внешний файл и загрузить его?
Я сделал; но большая часть моего опыта связана с jQuery.
@BlueDogRanch Почему ты хочешь это сделать?
@DaveNewton Спасибо :) Используя Javascript, я хочу показать тот или иной элемент HTML div в зависимости от текущей даты. Я использовал jQuery, но у меня были проблемы с его последовательной работой, я думаю, из-за DOM React.
@BlueDogRanch Как насчет того, чтобы сделать этот код перед return, сохранить результат в переменной и просто поместить {variable} в JSX? Да, есть и другие способы, которые делают именно то, о чем вы просите, например, IIFE, обычная функция, функциональный компонент, но imo. переменная - самое простое и чистое решение.
@BlueDogRanch взгляните на мой предоставленный фрагмент. Что касается useState, useContext и базовой структуры поставщика/потребителя родительских/дочерних компонентов --- Он также использует простой log() хук, который console.info содержит содержимое + метку времени. Я не знаю вашего варианта использования или кто бы отказался от очень простого рабочего примера - предоставьте свои собственные примеры и помогите людям учиться.
@ Томас Спасибо, я об этом не подумал; Я новичок в React.
@BlueDogRanch Вы имеете в виду условный рендеринг?
@WesleyLeMahieu Спасибо! Я посмотрю на ваш ответ; это выглядит сложнее, чем мне нужно. Я хочу показать тот или иной HTML-div в зависимости от текущей даты, определенной Javascript.
@DaveNewton В некотором смысле да, используя Javascript new Date(); и операторы < и > с фиксированными датами. То есть показывать один HTML div в понедельник, другой во вторник и т.д.
@Thomas Можете ли вы привести пример этого?
@BlueDogRanch Я хотел сказать, что можно искать «условный рендеринг reactjs». Тем не менее, я бы подумал о том, чтобы вытащить большую часть этого из рендера, который и без того довольно громоздкий. Не связано, но похоже, что вы дублируете существующие решения маршрутизации.
@DaveNewton Спасибо, я очень мало знаю React, и это не мой код; Я просто пытаюсь добавить функцию в простой Javascript.
@BlueDogRanch Я привел простой пример того, о чем говорит Дэйв. Он показывает другой div в зависимости от дня.
@RandyCasburn Вы можете просто вызвать console.info в JSX. Нравится <Example test = {console.info(…)}>{console.info(…)}</Example>. Конечно, это не очень полезно, так как будет отображать undefined, но вы можете легко вызывать другие функции, которые делают что-то (включая ведение журнала) и возвращают значения.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


В вашей ситуации есть два простых способа сделать это:
Создав свою функцию непосредственно внутри вашего блока render, а затем выполнив функцию в HTML, используя {} для переноса переменной:
render () {
const runJavascript = () => {
console.info('Hello World''); // execute plain JS here
var timestamp = Math.round((new Date()).getTime() / 1000);
};
if (singleColumn) {
return (
<div>{runJavascript()}</div>
);
}
return <div>hello world</div>;
}
Кроме того, вы можете создать свою функцию runJavascript вне блока рендеринга вместе с любыми блоками constructor, componentDidMount или componentDidUnmount, которые у вас могут быть:
runJavascript = () => {
console.info('Hello World''); // execute plain JS here
var timestamp = Math.round((new Date()).getTime() / 1000);
};
render () {
if (singleColumn) {
return (
<div>{this.runJavascript()}</div>
);
}
return <div>hello world</div>;
}
Спасибо! Это интересно. Итак, выходит ли блок const за пределы блока рендеринга? И я использую <div id = "root"></div> внутри блока рендеринга?
В React весь App изначально визуализируется с помощью ReactDOM и простого селектора JS. Это единственный раз, когда вы когда-либо увидите этот рендер --- Тогда у вас есть свой App, который вы можете рассматривать как корень вашего приложения/сайта. App, воскресенье и понедельник все React functional components. Таким образом, каждый должен return одно родительское тело JSX. Итак, в этом примере, когда приложение загружается, оно проверяет, что такое сегодня, и отображает другой компонент на основе этого. return null просто ничего не покажет - белая страница --- create-react-app.dev/docs/getting-started
Код React, который я разместил, в настоящее время является частью приложения (не моего), и я вообще не знаю React. Итак, день недели выводится в <div id = "root"></div>?
App компонент находится внутри <div id = "root"></div>, да! Вот как все приложения React «монтируются» или «инициализируются». Единственным фрагментом кода на чистом javascript был document.getElementById('root'). Остальное React.
Спасибо, это интересно, но я хотел бы посмотреть, как запустить Javascript прямо в файле.
Это довольно расплывчато — вы можете запускать Javascript где угодно в React. Могут возникнуть проблемы, если вы пытаетесь сохранить состояние, поэтому такие вещи, как useState, невероятно важны --- const timestamp = new Date().getDay(); это запускает javascript прямо в файле. Если вы имеете в виду попытку сделать это: return (<div>{const timestamp = new Date().getDay(); console.info(timestamp);}</div>), то это не совсем так. Я бы порекомендовал освежить в памяти все уроки по React Get Started --- Удачи!
Хорошо, но как именно я могу использовать ваш ответ в myfile.js? Я помещаю блок const за пределы блока рендеринга, но получаю токен Unexpected в const Monday = () => {...
Добавил пример для вас, если вам это нужно.
Спасибо! Я все еще попробую решение React, но прямо сейчас, для первого примера Javascript, я получаю «TypeError: document.getElementById(...) is null», так что есть проблема с кодом, работающим до завершения DOM, я думаю ; а второй пример выдает ошибку «присвоение необъявленной переменной runJavascript», так что, думаю, мне нужно объявить «runJavascript»?
Это то, что работает в простом приложении React. Я переместил простой Javascript из блоков рендеринга и возврата в начало файла (под вызовами импорта), а затем использовал 1) либо const для переменной timestampone. Или, 2) для переменной Javascript с HTML, dangerouslySetInnerHTML, что мне подходит, так как никто, кроме меня, не будет иметь доступа для вставки HTML.
App.js:
import * as React from 'react';
const timestampone = <span> {Math.round((new Date()).getTime() / 1000)} </span>;
var timestamptwo = Math.round((new Date()).getTime() / 1000);
if (timestamptwo >=1675893600 && timestamptwo <= 1675897200 ) {
var timedate = '<div class = "wrapper">Between Timestamps</div>';
}
function App() {
return (
<div className = "App">
timestampone: {timestampone}
<div dangerouslySetInnerHTML = {{__html: timedate}} />
</div>
);
}
export default App;
Вы пробовали добавить
console.infoв функцию?