2

react-bodymovin 非常适合我的 reactjs 应用程序,但是当迁移到 nextjs 时,它不起作用。我收到以下错误:

ReferenceError: window is not defined
    at Object.<anonymous> (/Users/xyz/work/web/dict/next/node_modules/bodymovin/build/player/bodymovin_light.min.js:1:226)
    at Module._compile (module.js:653:30)
    at Object.Module._extensions..js (module.js:664:10)
    at Module.load (module.js:566:32)
    at tryModuleLoad (module.js:506:12)
    at Function.Module._load (module.js:498:3)
    at Module.require (module.js:597:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/Users/xyz/work/web/dict/next/node_modules/react-bodymovin/lib/ReactBodymovin.js:2:17)
    at Module._compile (module.js:653:30)
    at Object.Module._extensions..js (module.js:664:10)
    at Module.load (module.js:566:32)
    at tryModuleLoad (module.js:506:12)
    at Function.Module._load (module.js:498:3)
    at Module.require (module.js:597:17)
    at require (internal/module.js:11:18)

Justa导入库bodymovin,会导致以上所有

import React, { Component } from 'react';
import Router from 'next/router';
import Layout from '../components/Layout';
import SuggestionList from '../components/SuggestionList';
import dict from '../api/dict';
import ReactBodymovin from 'react-bodymovin';

如果我按以下方式禁用,它可以工作

import React, { Component } from 'react';
import Router from 'next/router';
import Layout from '../components/Layout';
import SuggestionList from '../components/SuggestionList';
import dict from '../api/dict';
//import ReactBodymovin from 'react-bodymovin';
4

1 回答 1

6

您的问题很可能是由于使用了旧版本的 bodymovin/lottie,它没有服务器端渲染错误修复,因此找不到窗口,因为它在服务器端编译时不存在。

更多信息在这里:https ://github.com/zeit/next.js/wiki/FAQ#i-use-a-library-which-throws-window-is-undefined

要解决这个问题:

1)将正确的第3方添加到依赖项:“react-lottie”:“^1.2.3”

Lottie Web得到了 SSR 错误修复,应该更新react-lottie以避免窗口问题。

https://github.com/chenqingspring/react-lottie/issues/17

2) 将以下文件放在 ./pages/lottie.js

import React from "react";
import Lottie from "react-lottie";
import * as animationData from "../animations/loading-spinner-black.json";

export default class LottieControl extends React.Component {
constructor(props) {
    super(props);
    this.state = { isStopped: false, isPaused: false };
}

render() {
    const buttonStyle = {
    display: "block",
    margin: "10px auto"
    };

    console.log(animationData);

    const defaultOptions = {
    loop: true,
    autoplay: true,
    animationData: animationData.default,
    rendererSettings: {
        preserveAspectRatio: "xMidYMid slice"
    }
    };

    return (
    <div>
        <Lottie
        options={defaultOptions}
        height={400}
        width={400}
        isStopped={this.state.isStopped}
        isPaused={this.state.isPaused}
        />
        <button
        style={buttonStyle}
        onClick={() => this.setState({ isStopped: true })}
        >
        stop
        </button>
        <button
        style={buttonStyle}
        onClick={() => this.setState({ isStopped: false })}
        >
        play
        </button>
        <button
        style={buttonStyle}
        onClick={() => this.setState({ isPaused: !this.state.isPaused })}
        >
        pause
        </button>
    </div>
    );
}
}

3) 将以下文件放入 ./animations/loading-spinner-black.json

{"v":"5.1.8","fr":29.9700012207031,"ip":0,"op":60.0000024438501,"w":100,"h":100,"nm":"Spinner","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"spinner Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[50,50,0],"ix":2},"a":{"a":0,"k":[160,284,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,19.812],[19.882,0],[0,-19.882],[-19.882,0]],"o":[[0,-19.882],[-19.882,0],[0,19.882],[19.882,0]],"v":[[36,0],[0,-36],[-36,0],[0,36]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_1_0p167_0p167"],"t":0,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":29,"s":[0],"e":[0]},{"t":51.0000020772726}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":20,"s":[100],"e":[1]},{"t":60.0000024438501}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[160,284],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_1_0p167_0p167"],"t":0,"s":[-90],"e":[270]},{"t":59.0000024031193}],"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":60.0000024438501,"st":0,"bm":0}],"markers":[]}

4)“npm run dev”并转到http://localhost:3000/lottie,你应该会看到一个带有控件的黑色旋转动画

或者,如果您无法更改依赖项并通过 process.cient 强制使用客户端代码执行,则可以忽略上述内容。在此处查看更多详细信息。

希望这可以帮助。如果您还有其他问题,请告诉我,如果需要,我可以做一个活生生的例子。

于 2019-01-28T18:01:32.667 回答