React-js无法识别AmbientLightSensor

时间:2019-03-25 00:35:27

标签: javascript reactjs

我正在尝试通过感测器使用传感器的API,但我无法使其正常工作。

给我一​​个错误,说AmbientLightSensor (in my case this sensor)未定义

如果我在react ( more exactly with an extension from VSCode "live server" )之外运行脚本,它可以正常运行( just a html with some JS code in it )。 太酷了,但在这种情况下,至少我想在react中运行此脚本,但它只是不允许我这样做。

  

到目前为止,我已经尝试过:

  • 在运行此代码时,将其作为由componentDidMount调用的类方法进行响应(这就是我已经将JS代码放在其中^^)
  • 使用标记运行此代码,希望它可能不会真正使用我所知道的JS,并且可能在html内运行它将改变此代码...不,它并没有成功 所以在这一点上,我不确定该做什么才能检查

这是我的代码,我要运行的js代码在Did mount组件内部

class App extends Component {
    constructor(props) {
        super(props);
    }
    componentDidMount() {
        const details = document.getElementById("details");

        // Feature detection
        if (window.AmbientLightSensor) {
            try {
                const sensor = new AmbientLightSensor();
                // Detect changes in the light
                sensor.onreading = () => {
                    details.innerHTML = sensor.illuminance;

                    // Read the light levels in lux
                    // < 50 is dark room
                    if (sensor.illuminance < 50) {
                        document.body.className = "darkLight";
                    } else {
                        document.body.className = "brightLight";
                    }
                };

                // Has an error occured?
                sensor.onerror = event =>
                    (document.getElementById("details").innerHTML =
                        event.error.message);
                sensor.start();
            } catch (err) {
                details.innerHTML = err.message;
            }
        } else {
            details.innerHTML =
                "It looks like your browser doesnt support this feature";
        }
      }

    render() {
        return (
            <div className="app">
                <h1>Ambient Light Sensor</h1>
                <p>Current Light Levels</p>
                <div id="details"></div>
            </div>
        );
    }
}

这也是有效的html


<head>
    <meta charset="UTF-8" />
    <title>Ambient Light Sensor</title>
</head>

<body class="brightLight">
    <h1>Ambient Light Sensor</h1>
    <p>Current Light Levels</p>
    <div id="details"></div>
</body>
<script>
    const details = document.getElementById("details");

    // Feature detection
    if (window.AmbientLightSensor) {
        try {
            const sensor = new AmbientLightSensor();
            // Detect changes in the light
            sensor.onreading = () => {
                details.innerHTML = sensor.illuminance;

                // Read the light levels in lux
                // < 50 is dark room
                if (sensor.illuminance < 50) {
                    document.body.className = "darkLight";
                } else {
                    document.body.className = "brightLight";
                }
            };

            // Has an error occured?
            sensor.onerror = event =>
                (document.getElementById("details").innerHTML =
                    event.error.message);
            sensor.start();
        } catch (err) {
            details.innerHTML = err.message;
        }
    } else {
        details.innerHTML =
            "It looks like your browser doesnt support this feature";
    }
</script>

</html>```

PS* for this to work you need to run this on a https server

3 个答案:

答案 0 :(得分:1)

那不是React的工作方式...

我建议您在此处查看dangerouslySetInnerHTML链接:https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml

此处有createRef链接:https://reactjs.org/docs/refs-and-the-dom.html#creating-refs

这是一个简单的示例,利用两者为您提供了更好的主意:

import React from 'react';

class App extends React.Component {
  constructor(props) {
    super(props);
    this.detailsRef = React.createRef();
  }

  createMarkup() {
    return { __html: 'whatever you want...' };
  }

  componentDidMount() {
    console.log(this.detailsRef.current.innerHTML);
  }

  render() {
    return (
      <div className="app">
        <h1>Ambient Light Sensor</h1>
        <p>Current Light Levels</p>
        <div
          ref={this.detailsRef}
          dangerouslySetInnerHTML={this.createMarkup()}
        />
      </div>
    );
  }
}

export default App;

试用它,并阅读官方文档中的链接以适应您的特定用例...

答案 1 :(得分:1)

以前从未使用过AmbientLightSensor API,但是:请尝试以下操作:

class App extends Component {
    constructor(props) {
        super(props);
        this.state = {
            details: ''
        };
    }
    componentDidMount() {
        if (window.AmbientLightSensor) {
            try {
                const sensor = new AmbientLightSensor();

                sensor.onreading = () => {
                    this.setState({ details: sensor.illuminance });

                    if (sensor.illuminance < 50) {
                        document.body.className = 'darkLight';
                    } else {
                        document.body.className = 'brightLight';
                    }
                };
                sensor.onerror = event =>
                    this.setState({ details: event.error.message });

                sensor.start();
            } catch (err) {
                this.setState({ details: err.message });
            }
        } else {
            this.setState({
                details:
                    'It looks like your browser doesnt support this feature'
            });
        }
    }

    render() {
        return (
            <div className="app">
                <h1>Ambient Light Sensor</h1>
                <p>Current Light Levels</p>
                <div id="details">{this.state.details}</div>
            </div>
        );
    }
}

答案 2 :(得分:0)

好吧,我明白了:D 我发现发送JavaScript文件并运行<input id="mySlider" type="range" value="0" min="0" max="5" step="1"/> <div id="output"> <em>Not run yet</em> </div>的唯一工作方式(如果您使用create react app创建了应用程序)

is by declaring it in the index.html file inside the public folder

之所以无法在React类中运行脚本(据我所了解)的原因是,React实际上并没有在Normally react servers you this file and it adds it's components over it. 上运行,而是基于{{1 }}。

虽然这意味着您可能已经习惯了大多数功能,但也有例外,主要是新功能(作为传感器的API,这是很新的功能)。

这将来可能不是问题,但就目前而言,我认为这是一种解决方法。

  

编辑* @SakoBu的答案原来是安全的方法   这个

     

(#改变主意meme:3)