ReactJS - 意外的“`”

ReactJS - Unexpected "`"

我想使用这个反应网格:http://codepen.io/anon/pen/yOEbyw

在我的 php/symfony 前端。

我已经包含了那个 codepen 中的 JS 文件

但我遇到了一个 twig 语法错误:意外的“`”

以下是我在 html.twig

中的整理方式
<!DOCTYPE html>
<html>
<head>
    <meta charset=”utf-8">
    <title>React Tutorial</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.6/react.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.6/react-dom.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/redux/3.0.5/redux.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/4.0.6/react-redux.js"></script>
</head>
<body>
<div id="content"></div>
<div id="react-root"></div>



<script src="https://unpkg.com/react@15.0.1/dist/react-with-addons.min.js"></script>
<script src="https://unpkg.com/react-dom@15.0.1/dist/react-dom.min.js"></script>
<script src="https://npmcdn.com/react-motion@0.4.2/build/react-motion.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.6.1/lodash.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.24.0/babel.js"></script>




<script type="text/babel">




const dataStructure = [ // structure that models our initial rendered view of items
    [0, 1, 2],
    [3, 4, 5, 6, 7],
    [8, 9, 10, 11]
]

const reinsert = (array, colFrom, rowFrom, colTo, rowTo) => {
    const _array = array.slice(0);
    const val = _array[colFrom][rowFrom];
    _array[colFrom].splice(rowFrom, 1);
    _array[colTo].splice(rowTo, 0, val);
    calculateVisiblePositions(_array);
    return _array;
}

const gutterPadding = 21;
const clamp = (n, min, max) => Math.max(Math.min(n, max), min);
const getColumnWidth = () => (window.innerWidth / dataStructure.length) - (gutterPadding / dataStructure.length); // spread columns over available window width
const height = 110;

let width = getColumnWidth(),
    layout = null;

// items are ordered by their index in this visual positions array
const calculateVisiblePositions = (newOrder) => {
    width = getColumnWidth();
    layout = newOrder.map((column, col) => {
       return _.range(column.length + 1).map((item, row) => {
           return [width * col, height * row];
       });
   });
}

// define spring motion opts
const springSetting1 = {stiffness: 333, damping: 15};
const springSetting2 = {stiffness: 333, damping: 22};

const List = React.createClass({
    getInitialState() {
        return {
            mouse: [0, 0],
            delta: [0, 0], // difference between mouse and item position, for dragging
            lastPress: null, // key of the last pressed component
            currentColumn: null,
            isPressed: false,
            order: dataStructure, // index: visual position. value: component key/id
            isResizing: false
        };
    },

    componentWillMount() {
        this.resizeTimeout = null;
        calculateVisiblePositions(dataStructure);
    },

    componentDidMount() {
        window.addEventListener('touchmove', this.handleTouchMove);
        window.addEventListener('mousemove', this.handleMouseMove);
        window.addEventListener('touchend', this.handleMouseUp);
        window.addEventListener('mouseup', this.handleMouseUp);
        window.addEventListener('resize', this.handleResize);
    },

    componentWillUnmount() {
        window.removeEventListener('resize', this.handleResize);
    },

    handleTouchStart(key, currentColumn, pressLocation, e) {
         console.log('currentColumn: ' + currentColumn);
        this.handleMouseDown(key, currentColumn, pressLocation, e.touches[0]);
    },

    handleTouchMove(e) {
        e.preventDefault();
        this.handleMouseMove(e.touches[0]);
    },

    handleMouseMove({pageX, pageY}) {
        const {order, lastPress, currentColumn: colFrom, isPressed, delta: [dx, dy]} = this.state;
         console.log('colFrom: ' + colFrom);
        if (isPressed) {
            const mouse = [pageX - dx, pageY - dy];
            const colTo = clamp(Math.floor((mouse[0] + (width / 2)) / width), 0, 6);
            const rowTo = clamp(Math.floor((mouse[1] + (height / 2)) / height), 0, 100);
            const rowFrom = order[colFrom].indexOf(lastPress);
            const newOrder = reinsert(order, colFrom, rowFrom, colTo, rowTo);
            this.setState({
                mouse,
                order: newOrder,
                currentColumn: colTo
            });
        }
    },

    handleMouseDown(key, currentColumn, [pressX, pressY], {pageX, pageY}) {
        this.setState({
            lastPress: key,
            currentColumn,
            isPressed: true,
            delta: [pageX - pressX, pageY - pressY],
            mouse: [pressX, pressY],
        });
    },

    handleMouseUp() {
        this.setState({
            isPressed: false,
            delta: [0, 0]
        });
    },

    handleResize() {
        clearTimeout(this.resizeTimeout);
        this.applyResizingState(true);
        // resize one last time after resizing stops, as sometimes this can be a little janky sometimes...
        this.resizeTimeout = setTimeout(() => this.applyResizingState(false), 100);
    },

    applyResizingState(isResizing) {
        this.setState({ isResizing });
        calculateVisiblePositions(dataStructure);
    },

    render() {
        const { order, lastPress, currentColumn, isPressed, mouse, isResizing } = this.state;
        return (
            <div className="items">
                {order.map( (column, colIndex) => {
                    return (
                        column.map( (row) => {
                            let style,
                                x,
                                y,
                                visualPosition = order[colIndex].indexOf(row),
                                isActive = (row === lastPress && colIndex === currentColumn && isPressed);

                            if(isActive) {
                                [x, y] = mouse;
                                style = {
                                    translateX: x,
                                    translateY: y,
                                    scale: ReactMotion.spring(1.1, springSetting1)
                                };
                            } else if(isResizing) {
                                [x, y] = layout[colIndex][visualPosition];
                                style = {
                                    translateX: x,
                                    translateY: y,
                                    scale: 1
                                };
                            } else {
                                [x, y] = layout[colIndex][visualPosition];
                                style = {
                                    translateX: ReactMotion.spring(x, springSetting2),
                                    translateY: ReactMotion.spring(y, springSetting2),
                                    scale: ReactMotion.spring(1, springSetting1)
                                };
                            }

                            return (
                                <ReactMotion.Motion key={row} style={style}>
                                    {({translateX, translateY, scale}) =>
                                    <div
                                        onMouseDown={this.handleMouseDown.bind(null, row, colIndex, [x, y])}
                                        onTouchStart={this.handleTouchStart.bind(null, row, colIndex, [x, y])}
                                        className={isActive ? 'item is-active' : 'item'}
                                        style={{
                                            WebkitTransform: `translate3d(${translateX}px, ${translateY}px, 0) scale(${scale})`,
                                            transform: `translate3d(${translateX}px, ${translateY}px, 0) scale(${scale})`,
                                            zIndex: (row === lastPress && colIndex === currentColumn) ? 99 : visualPosition,
                                        }}
                                    >Item {row + 1}</div>
                                    }
                                </ReactMotion.Motion>
                            )
                        })
                    )
                })}
            </div>
        )
    }
});

ReactDOM.render(<List />, document.getElementById('react-root'));






</script>

</body>
</html>

Twig 使用 {{...}} 来标记模板的位。在定义 style 属性时出现在 <script> 标签内:

style={{
  WebkitTransform: `translate3d(${translateX}px, ${translateY}px, 0) scale(${scale})`,
  transform: `translate3d(${translateX}px, ${translateY}px, 0) scale(${scale})`,
  zIndex: (row === lastPress && colIndex === currentColumn) ? 99 : visualPosition,
}}

您可以通过在两个开头的卷曲之间添加 space 来解决此问题:style={ {

或者,mark the whole script verbatim

{% verbatim %}
<script type="text/babel">
...
</script>
{% endverbatim %}